diff --git a/integration/EasyAbp.EShop/test/EasyAbp.EShop.EntityFrameworkCore.Tests/EasyAbp.EShop.EntityFrameworkCore.Tests.csproj b/integration/EasyAbp.EShop/test/EasyAbp.EShop.EntityFrameworkCore.Tests/EasyAbp.EShop.EntityFrameworkCore.Tests.csproj index 821710c3..86e49d55 100644 --- a/integration/EasyAbp.EShop/test/EasyAbp.EShop.EntityFrameworkCore.Tests/EasyAbp.EShop.EntityFrameworkCore.Tests.csproj +++ b/integration/EasyAbp.EShop/test/EasyAbp.EShop.EntityFrameworkCore.Tests/EasyAbp.EShop.EntityFrameworkCore.Tests.csproj @@ -7,11 +7,10 @@ - - + diff --git a/integration/EasyAbp.EShop/test/EasyAbp.EShop.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopEntityFrameworkCoreTestModule.cs b/integration/EasyAbp.EShop/test/EasyAbp.EShop.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopEntityFrameworkCoreTestModule.cs index 9b851b97..30d9612c 100644 --- a/integration/EasyAbp.EShop/test/EasyAbp.EShop.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopEntityFrameworkCoreTestModule.cs +++ b/integration/EasyAbp.EShop/test/EasyAbp.EShop.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopEntityFrameworkCoreTestModule.cs @@ -3,14 +3,16 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; namespace EasyAbp.EShop.EntityFrameworkCore { [DependsOn( typeof(EShopTestBaseModule), - typeof(EShopEntityFrameworkCoreModule) - )] + typeof(EShopEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqliteModule) + )] public class EShopEntityFrameworkCoreTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json index 75fe3af4..6c004aef 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Localization/Orders/en.json @@ -61,7 +61,7 @@ "OrderExtraFeeRefundAmount": "Refund amount", "EasyAbp.EShop.Orders:UnexpectedCurrency": "Only the specified currency {expectedCurrency} is allowed.", "EasyAbp.EShop.Orders:OrderLineInvalidQuantity": "Invalid quantity {quantity} for product {productId} (SKU: {productSkuId}).", - "EasyAbp.EShop.Orders:DiscountAmountOverflow": "The discount amount overflow.", + "EasyAbp.EShop.Orders:DiscountAmountOverflow": "The discount amount overflows.", "EasyAbp.EShop.Orders:DuplicateOrderDiscount": "The discount {discountName} (key: {discountKey}) of order line {orderLineId} already exists.", "EasyAbp.EShop.Orders:DuplicateOrderExtraFee": "The extra fee {extraFeeName} (key: {extraFeeKey}) already exists.", "EasyAbp.EShop.Orders:InvalidOrderExtraFee": "The extra fee {extraFee} is invalid.", diff --git a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderDiscountInfoModel.cs b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/OrderDiscountInfoModel.cs similarity index 69% rename from modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderDiscountInfoModel.cs rename to modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/OrderDiscountInfoModel.cs index 0e0aec48..d085c36c 100644 --- a/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderDiscountInfoModel.cs +++ b/modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain.Shared/EasyAbp/EShop/Orders/Orders/OrderDiscountInfoModel.cs @@ -1,4 +1,5 @@ using System; +using EasyAbp.EShop.Products.Products; using JetBrains.Annotations; namespace EasyAbp.EShop.Orders.Orders; @@ -18,16 +19,12 @@ public class OrderDiscountInfoModel public decimal DiscountedAmount { get; set; } - public OrderDiscountInfoModel( - Guid orderLineId, - [NotNull] string name, - [CanBeNull] string key, - [CanBeNull] string displayName, - decimal discountedAmount) + public OrderDiscountInfoModel(Guid orderLineId, [NotNull] string name, [CanBeNull] string key, + [CanBeNull] string displayName, decimal discountedAmount) { OrderLineId = orderLineId; Name = name; - Key = key ?? string.Empty; + Key = key; DisplayName = displayName; DiscountedAmount = discountedAmount; } diff --git a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests.csproj b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests.csproj index 78869d99..c56c823b 100644 --- a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests.csproj +++ b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests.csproj @@ -7,11 +7,10 @@ - - + diff --git a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopOrdersEntityFrameworkCoreTestModule.cs b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopOrdersEntityFrameworkCoreTestModule.cs index 3c038946..f4ef196d 100644 --- a/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopOrdersEntityFrameworkCoreTestModule.cs +++ b/modules/EasyAbp.EShop.Orders/test/EasyAbp.EShop.Orders.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopOrdersEntityFrameworkCoreTestModule.cs @@ -3,14 +3,16 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Orders.EntityFrameworkCore { [DependsOn( typeof(EShopOrdersTestBaseModule), - typeof(EShopOrdersEntityFrameworkCoreModule) - )] + typeof(EShopOrdersEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqliteModule) + )] public class EShopOrdersEntityFrameworkCoreTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/modules/EasyAbp.EShop.Payments/test/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests.csproj b/modules/EasyAbp.EShop.Payments/test/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests.csproj index 9600131d..d825db46 100644 --- a/modules/EasyAbp.EShop.Payments/test/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests.csproj +++ b/modules/EasyAbp.EShop.Payments/test/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests.csproj @@ -7,11 +7,10 @@ - - + diff --git a/modules/EasyAbp.EShop.Payments/test/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopPaymentsEntityFrameworkCoreTestModule.cs b/modules/EasyAbp.EShop.Payments/test/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopPaymentsEntityFrameworkCoreTestModule.cs index 9cbabbba..34d5add7 100644 --- a/modules/EasyAbp.EShop.Payments/test/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopPaymentsEntityFrameworkCoreTestModule.cs +++ b/modules/EasyAbp.EShop.Payments/test/EasyAbp.EShop.Payments.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopPaymentsEntityFrameworkCoreTestModule.cs @@ -3,14 +3,16 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Payments.EntityFrameworkCore { [DependsOn( typeof(EShopPaymentsTestBaseModule), - typeof(EShopPaymentsEntityFrameworkCoreModule) - )] + typeof(EShopPaymentsEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqliteModule) + )] public class EShopPaymentsEntityFrameworkCoreTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/modules/EasyAbp.EShop.Plugins/test/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests.csproj b/modules/EasyAbp.EShop.Plugins/test/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests.csproj index 0d165405..44f16a77 100644 --- a/modules/EasyAbp.EShop.Plugins/test/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests.csproj +++ b/modules/EasyAbp.EShop.Plugins/test/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests.csproj @@ -7,11 +7,10 @@ - - + diff --git a/modules/EasyAbp.EShop.Plugins/test/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopPluginsEntityFrameworkCoreTestModule.cs b/modules/EasyAbp.EShop.Plugins/test/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopPluginsEntityFrameworkCoreTestModule.cs index 40e31822..1bf1d851 100644 --- a/modules/EasyAbp.EShop.Plugins/test/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopPluginsEntityFrameworkCoreTestModule.cs +++ b/modules/EasyAbp.EShop.Plugins/test/EasyAbp.EShop.Plugins.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopPluginsEntityFrameworkCoreTestModule.cs @@ -3,14 +3,16 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Plugins.EntityFrameworkCore { [DependsOn( typeof(EShopPluginsTestBaseModule), - typeof(EShopPluginsEntityFrameworkCoreModule) - )] + typeof(EShopPluginsEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqliteModule) + )] public class EShopPluginsEntityFrameworkCoreTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs index 21e8686c..e183ccfe 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductSkuDto.cs @@ -1,36 +1,40 @@ using System; using System.Collections.Generic; using Volo.Abp.Application.Dtos; -using Volo.Abp.Data; namespace EasyAbp.EShop.Products.Products.Dtos { [Serializable] - public class ProductSkuDto : ExtensibleFullAuditedEntityDto, IProductSku + public class ProductSkuDto : ExtensibleFullAuditedEntityDto, IProductSku, IHasFullDiscountsInfo { public List AttributeOptionIds { get; set; } + public string Name { get; set; } - + public string Currency { get; set; } - + public decimal? OriginalPrice { get; set; } - + + public decimal PriceWithoutDiscount { get; set; } + public decimal Price { get; set; } - - public decimal DiscountedPrice { get; set; } - + + public List ProductDiscounts { get; set; } = new(); + + public List OrderDiscountPreviews { get; set; } = new(); + public int Inventory { get; set; } - + public long Sold { get; set; } - + public int OrderMinQuantity { get; set; } - + public int OrderMaxQuantity { get; set; } - + public TimeSpan? PaymentExpireIn { get; set; } public string MediaResources { get; set; } - + public Guid? ProductDetailId { get; set; } } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductViewDto.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductViewDto.cs index 6de98b2e..87ade88b 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductViewDto.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application.Contracts/EasyAbp/EShop/Products/Products/Dtos/ProductViewDto.cs @@ -1,15 +1,18 @@ using System; +using System.Collections.Generic; using Volo.Abp.Application.Dtos; namespace EasyAbp.EShop.Products.Products.Dtos { [Serializable] - public class ProductViewDto : ExtensibleCreationAuditedEntityDto, IProductBase, IHasProductGroupDisplayName + public class ProductViewDto : ExtensibleCreationAuditedEntityDto, IProductView { public Guid StoreId { get; set; } public string ProductGroupName { get; set; } + public string ProductGroupDisplayName { get; set; } + public Guid? ProductDetailId { get; set; } public string UniqueName { get; set; } @@ -38,8 +41,16 @@ namespace EasyAbp.EShop.Products.Products.Dtos public decimal? MaximumPrice { get; set; } + public decimal? MinimumPriceWithoutDiscount { get; set; } + + public decimal? MaximumPriceWithoutDiscount { get; set; } + public long Sold { get; set; } - public string ProductGroupDisplayName { get; set; } + public decimal PriceWithoutDiscount { get; set; } + + public List ProductDiscounts { get; set; } = new(); + + public List OrderDiscountPreviews { get; set; } = new(); } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs index d665704a..b2496bc9 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductAppService.cs @@ -312,8 +312,10 @@ namespace EasyAbp.EShop.Products.Products var priceDataModel = await _productManager.GetRealPriceAsync(product, productSku); - productSkuDto.Price = priceDataModel.Price; - productSkuDto.DiscountedPrice = priceDataModel.DiscountedPrice; + productSkuDto.PriceWithoutDiscount = priceDataModel.PriceWithoutDiscount; + productSkuDto.Price = priceDataModel.DiscountedPrice; + productSkuDto.ProductDiscounts = priceDataModel.ProductDiscounts; + productSkuDto.OrderDiscountPreviews = priceDataModel.OrderDiscountPreviews; } if (productDto.ProductSkus.Count > 0) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductViewAppService.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductViewAppService.cs index 69a83754..e9235266 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductViewAppService.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/Products/ProductViewAppService.cs @@ -9,7 +9,6 @@ using EasyAbp.EShop.Products.Settings; using EasyAbp.EShop.Stores.Stores; using Microsoft.Extensions.Caching.Distributed; using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; using Volo.Abp.Caching; using Volo.Abp.Uow; @@ -150,23 +149,62 @@ namespace EasyAbp.EShop.Products.Products } decimal? min = null, max = null; + decimal? minWithoutDiscount = null, maxWithoutDiscount = null; + + var discounts = new DiscountsInfoModel(); foreach (var productSku in product.ProductSkus) { + var overrideProductDiscounts = false; var priceDataModel = await _productManager.GetRealPriceAsync(product, productSku); - if (min is null || priceDataModel.Price < min.Value) + if (min is null || priceDataModel.DiscountedPrice < min.Value) + { + min = priceDataModel.DiscountedPrice; + overrideProductDiscounts = true; + } + + if (max is null || priceDataModel.DiscountedPrice > max.Value) + { + max = priceDataModel.DiscountedPrice; + } + + if (minWithoutDiscount is null || priceDataModel.PriceWithoutDiscount < minWithoutDiscount.Value) { - min = productSku.Price; + minWithoutDiscount = priceDataModel.PriceWithoutDiscount; + } + + if (maxWithoutDiscount is null || priceDataModel.PriceWithoutDiscount > maxWithoutDiscount.Value) + { + maxWithoutDiscount = priceDataModel.PriceWithoutDiscount; + } + + foreach (var model in priceDataModel.ProductDiscounts) + { + var discount = discounts.FindProductDiscount(model.Name, model.Key); + + if (discount is null || overrideProductDiscounts) + { + discounts.AddOrUpdateProductDiscount(new ProductDiscountInfoModel(model.Name, model.Key, + model.DisplayName, model.DiscountedAmount, model.FromTime, model.ToTime)); + } } - if (max is null || priceDataModel.Price > max.Value) + foreach (var model in priceDataModel.OrderDiscountPreviews) { - max = productSku.Price; + var discount = discounts.FindOrderDiscount(model.Name, model.Key); + + if (discount is null) + { + discounts.AddOrUpdateOrderDiscountPreview(new OrderDiscountPreviewInfoModel(model.Name, + model.Key, model.DisplayName, model.MinDiscountedAmount, model.MaxDiscountedAmount, + model.FromTime, model.ToTime)); + } } } - productView.SetPrices(min, max); + productView.SetPrices(min, max, minWithoutDiscount, maxWithoutDiscount); + productView.SetDiscounts(discounts); } } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs index 0a19e6f6..ce85f7ff 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Application/EasyAbp/EShop/Products/ProductsApplicationAutoMapperProfile.cs @@ -34,7 +34,6 @@ namespace EasyAbp.EShop.Products CreateMap(); CreateMap() .Ignore(dto => dto.Price) - .Ignore(dto => dto.DiscountedPrice) .Ignore(dto => dto.Inventory) .Ignore(dto => dto.Sold); CreateMap(MemberList.Source) diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json index 7d1cca8d..ddb8139d 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/en.json @@ -98,6 +98,8 @@ "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "Should ensure SKUs are empty if you want to modify attributes of a product.", "EasyAbp.EShop.Products:StaticProductCannotBeModified": "Cannot modify the static product: {productId}", "EasyAbp.EShop.Products:StoreIsNotProductOwner": "Store {storeId} is not a owner of the product {productId}", - "EasyAbp.EShop.Products:InventoryInsufficient": "The inventory of the product {productId} (SKU: {productSkuId}) is insufficient, {quantity} are needed, but only {inventory}." + "EasyAbp.EShop.Products:InventoryInsufficient": "The inventory of the product {productId} (SKU: {productSkuId}) is insufficient, {quantity} are needed, but only {inventory}.", + "EasyAbp.EShop.Products:DiscountAmountOverflow": "The discount amount overflows.", + "EasyAbp.EShop.Products:InvalidTimePeriod": "Invalid time period." } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json index 4548d048..2f170274 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hans.json @@ -95,6 +95,8 @@ "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "请先确保Sku为空再修改商品的属性", "EasyAbp.EShop.Products:StaticProductCannotBeModified": "不能修改静态商品{productId}", "EasyAbp.EShop.Products:StoreIsNotProductOwner": "商店{storeId}不是商品{productId}的所有者 ", - "EasyAbp.EShop.Products:InventoryInsufficient": "产品{productId} (SKU: {productSkuId})的库存不足,需要数量{quantity},但是只有数量{inventory}" + "EasyAbp.EShop.Products:InventoryInsufficient": "产品{productId} (SKU: {productSkuId})的库存不足,需要数量{quantity},但是只有数量{inventory}", + "EasyAbp.EShop.Products:DiscountAmountOverflow": "折扣金额溢出", + "EasyAbp.EShop.Products:InvalidTimePeriod": "不正确的时间区间" } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json index 6f94539f..8bed6416 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Localization/Products/zh-Hant.json @@ -95,6 +95,8 @@ "EasyAbp.EShop.Products:ProductAttributesModificationFailed": "請先確保Sku為空再修改商品的屬性", "EasyAbp.EShop.Products:StaticProductCannotBeModified": "不能修改靜態商品{productId}", "EasyAbp.EShop.Products:StoreIsNotProductOwner": "商店{storeId}不是商品{productId}的所有者 ", - "EasyAbp.EShop.Products:InventoryInsufficient": "產品{productId} (SKU: {productSkuId})的庫存不足,需要數量{quantity},但是只有數量{inventory}" + "EasyAbp.EShop.Products:InventoryInsufficient": "產品{productId} (SKU: {productSkuId})的庫存不足,需要數量{quantity},但是只有數量{inventory}", + "EasyAbp.EShop.Products:DiscountAmountOverflow": "折扣金額溢出", + "EasyAbp.EShop.Products:InvalidTimePeriod": "不正確的時間區間" } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountAmountOverflowException.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountAmountOverflowException.cs new file mode 100644 index 00000000..fae95dc9 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountAmountOverflowException.cs @@ -0,0 +1,10 @@ +using Volo.Abp; + +namespace EasyAbp.EShop.Products.Products; + +public class DiscountAmountOverflowException : BusinessException +{ + public DiscountAmountOverflowException() : base(ProductsErrorCodes.DiscountAmountOverflow) + { + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountInfoModel.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountInfoModel.cs new file mode 100644 index 00000000..97180c2a --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountInfoModel.cs @@ -0,0 +1,45 @@ +using System; +using JetBrains.Annotations; + +namespace EasyAbp.EShop.Products.Products; + +public abstract class DiscountInfoModel +{ + [NotNull] + public string Name { get; set; } + + [CanBeNull] + public string Key { get; set; } + + [CanBeNull] + public string DisplayName { get; set; } + + /// + /// When the discount begins to take effect. + /// + public DateTime? FromTime { get; set; } + + /// + /// When the discount ends. + /// + public DateTime? ToTime { get; set; } + + public DiscountInfoModel() + { + } + + public DiscountInfoModel([NotNull] string name, [CanBeNull] string key, [CanBeNull] string displayName, + DateTime? fromTime, DateTime? toTime) + { + if (fromTime > toTime) + { + throw new InvalidTimePeriodException(); + } + + Name = name; + Key = key; + DisplayName = displayName; + FromTime = fromTime; + ToTime = toTime; + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountsInfoModel.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountsInfoModel.cs new file mode 100644 index 00000000..d4457396 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/DiscountsInfoModel.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace EasyAbp.EShop.Products.Products; + +public class DiscountsInfoModel : IHasDiscountsInfo +{ + public List ProductDiscounts { get; set; } + + public List OrderDiscountPreviews { get; set; } + + public DiscountsInfoModel() + { + ProductDiscounts = new List(); + OrderDiscountPreviews = new List(); + } + + public DiscountsInfoModel(List productDiscounts, + List orderDiscountPreviews) + { + ProductDiscounts = productDiscounts ?? new List(); + OrderDiscountPreviews = orderDiscountPreviews ?? new List(); + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/HasDiscountsInfoExtensions.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/HasDiscountsInfoExtensions.cs new file mode 100644 index 00000000..dc96aa4c --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/HasDiscountsInfoExtensions.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using JetBrains.Annotations; + +namespace EasyAbp.EShop.Products.Products; + +public static class HasDiscountsInfoExtensions +{ + public static decimal GetProductDiscountsDiscountedAmount(this IHasDiscountsInfo hasDiscountsInfo, DateTime now) + { + return hasDiscountsInfo.ProductDiscounts + .Where(x => !x.FromTime.HasValue || x.FromTime <= now) + .Where(x => !x.ToTime.HasValue || now <= x.ToTime) + .Sum(x => x.DiscountedAmount); + } + + public static void AddOrUpdateProductDiscount(this IHasDiscountsInfo hasDiscountsInfo, + ProductDiscountInfoModel model) + { + var found = hasDiscountsInfo.FindProductDiscount(model.Name, model.Key); + + if (found is null) + { + hasDiscountsInfo.ProductDiscounts.Add(model); + } + else + { + hasDiscountsInfo.ProductDiscounts.ReplaceOne(found, model); + } + + hasDiscountsInfo.CheckDiscountedAmount(); + } + + public static ProductDiscountInfoModel FindProductDiscount(this IHasDiscountsInfo hasDiscountsInfo, + [NotNull] string name, [CanBeNull] string key) + { + return hasDiscountsInfo.ProductDiscounts.Find(x => x.Name == name && x.Key == key); + } + + public static bool TryRemoveProductDiscount(this IHasDiscountsInfo hasDiscountsInfo, [NotNull] string name, + [CanBeNull] string key) + { + var found = hasDiscountsInfo.FindProductDiscount(name, key); + + if (found is null) + { + return false; + } + + hasDiscountsInfo.ProductDiscounts.Remove(found); + + hasDiscountsInfo.CheckDiscountedAmount(); + + return true; + } + + public static void AddOrUpdateOrderDiscountPreview(this IHasDiscountsInfo hasDiscountsInfo, + OrderDiscountPreviewInfoModel model) + { + var found = hasDiscountsInfo.FindOrderDiscount(model.Name, model.Key); + + if (found is null) + { + hasDiscountsInfo.OrderDiscountPreviews.Add(model); + } + else + { + hasDiscountsInfo.OrderDiscountPreviews.ReplaceOne(found, model); + } + + hasDiscountsInfo.CheckDiscountedAmount(); + } + + public static OrderDiscountPreviewInfoModel FindOrderDiscount(this IHasDiscountsInfo hasDiscountsInfo, + [NotNull] string name, [CanBeNull] string key) + { + return hasDiscountsInfo.OrderDiscountPreviews.Find(x => x.Name == name && x.Key == key); + } + + public static bool TryRemoveOrderDiscountPreview(this IHasDiscountsInfo hasDiscountsInfo, [NotNull] string name, + [CanBeNull] string key) + { + var found = hasDiscountsInfo.FindOrderDiscount(name, key); + + if (found is null) + { + return false; + } + + hasDiscountsInfo.OrderDiscountPreviews.Remove(found); + + hasDiscountsInfo.CheckDiscountedAmount(); + + return true; + } + + private static void CheckDiscountedAmount(this IHasDiscountsInfo hasDiscountsInfo) + { + if (hasDiscountsInfo.ProductDiscounts.Any(x => x.DiscountedAmount < decimal.Zero) || + hasDiscountsInfo.OrderDiscountPreviews.Any(x => + x.MinDiscountedAmount < decimal.Zero || x.MaxDiscountedAmount < decimal.Zero || + x.MinDiscountedAmount > x.MaxDiscountedAmount)) + { + throw new DiscountAmountOverflowException(); + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IHasDiscountsInfo.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IHasDiscountsInfo.cs new file mode 100644 index 00000000..56c8af4d --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IHasDiscountsInfo.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace EasyAbp.EShop.Products.Products; + +public interface IHasDiscountsInfo +{ + /// + /// The Price of the ProductSku has been subtracted from these product discounts. + /// + List ProductDiscounts { get; } + + /// + /// These order discount previews do not change the Price. They will be effective after placing an order. + /// + List OrderDiscountPreviews { get; } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IHasFullDiscountsInfo.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IHasFullDiscountsInfo.cs new file mode 100644 index 00000000..44edfc55 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IHasFullDiscountsInfo.cs @@ -0,0 +1,9 @@ +namespace EasyAbp.EShop.Products.Products; + +public interface IHasFullDiscountsInfo : IHasDiscountsInfo +{ + /// + /// The realtime price without subtracting the discount amount. + /// + decimal PriceWithoutDiscount { get; } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductSku.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductSku.cs index c1d78ef7..df8df3f4 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductSku.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductSku.cs @@ -14,8 +14,15 @@ namespace EasyAbp.EShop.Products.Products [NotNull] string Currency { get; } + /// + /// The official pricing value. + /// This property is only used for UI. + /// decimal? OriginalPrice { get; } + /// + /// The realtime price. + /// decimal Price { get; } int OrderMinQuantity { get; } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductView.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductView.cs new file mode 100644 index 00000000..23e3866e --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/IProductView.cs @@ -0,0 +1,14 @@ +namespace EasyAbp.EShop.Products.Products; + +public interface IProductView : IProductBase, IHasDiscountsInfo, IHasProductGroupDisplayName +{ + decimal? MinimumPrice { get; } + + decimal? MaximumPrice { get; } + + decimal? MinimumPriceWithoutDiscount { get; } + + decimal? MaximumPriceWithoutDiscount { get; } + + long Sold { get; } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/InvalidTimePeriodException.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/InvalidTimePeriodException.cs new file mode 100644 index 00000000..5c9d2622 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/InvalidTimePeriodException.cs @@ -0,0 +1,10 @@ +using Volo.Abp; + +namespace EasyAbp.EShop.Products.Products; + +public class InvalidTimePeriodException : BusinessException +{ + public InvalidTimePeriodException() : base(ProductsErrorCodes.InvalidTimePeriod) + { + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/OrderDiscountPreviewInfoModel.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/OrderDiscountPreviewInfoModel.cs new file mode 100644 index 00000000..99a45fae --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/OrderDiscountPreviewInfoModel.cs @@ -0,0 +1,67 @@ +using System; +using JetBrains.Annotations; + +namespace EasyAbp.EShop.Products.Products; + +[Serializable] +public class OrderDiscountPreviewInfoModel : DiscountInfoModel, ICloneable +{ + public decimal MinDiscountedAmount { get; set; } + + public decimal MaxDiscountedAmount { get; set; } + + public OrderDiscountPreviewInfoModel() + { + } + + public OrderDiscountPreviewInfoModel([NotNull] string name, [CanBeNull] string key, [CanBeNull] string displayName, + decimal minDiscountedAmount, decimal maxDiscountedAmount, DateTime? fromTime, DateTime? toTime) : base(name, + key, displayName, fromTime, toTime) + { + if (minDiscountedAmount < decimal.Zero || maxDiscountedAmount < decimal.Zero || + minDiscountedAmount > maxDiscountedAmount) + { + throw new DiscountAmountOverflowException(); + } + + MinDiscountedAmount = minDiscountedAmount; + MaxDiscountedAmount = maxDiscountedAmount; + } + + public object Clone() + { + return new OrderDiscountPreviewInfoModel(Name, Key, DisplayName, MinDiscountedAmount, MaxDiscountedAmount, + FromTime, ToTime); + } + + public override bool Equals(object obj) + { + return obj is OrderDiscountPreviewInfoModel other && Equals(other); + } + + protected bool Equals(OrderDiscountPreviewInfoModel other) + { + return Name == other.Name && + Key == other.Key && + DisplayName == other.DisplayName && + MinDiscountedAmount == other.MinDiscountedAmount && + MaxDiscountedAmount == other.MaxDiscountedAmount && + Nullable.Equals(FromTime, other.FromTime) && + Nullable.Equals(ToTime, other.ToTime); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Name.GetHashCode(); + hashCode = (hashCode * 397) ^ (Key != null ? Key.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (DisplayName != null ? DisplayName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ MinDiscountedAmount.GetHashCode(); + hashCode = (hashCode * 397) ^ MaxDiscountedAmount.GetHashCode(); + hashCode = (hashCode * 397) ^ FromTime.GetHashCode(); + hashCode = (hashCode * 397) ^ ToTime.GetHashCode(); + return hashCode; + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductDiscountInfoModel.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductDiscountInfoModel.cs new file mode 100644 index 00000000..53ae0180 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/Products/ProductDiscountInfoModel.cs @@ -0,0 +1,59 @@ +using System; +using JetBrains.Annotations; + +namespace EasyAbp.EShop.Products.Products; + +[Serializable] +public class ProductDiscountInfoModel : DiscountInfoModel, ICloneable +{ + public decimal DiscountedAmount { get; set; } + + public ProductDiscountInfoModel() + { + } + + public ProductDiscountInfoModel([NotNull] string name, [CanBeNull] string key, [CanBeNull] string displayName, + decimal discountedAmount, DateTime? fromTime, DateTime? toTime) : base(name, key, displayName, fromTime, toTime) + { + if (discountedAmount < decimal.Zero) + { + throw new DiscountAmountOverflowException(); + } + + DiscountedAmount = discountedAmount; + } + + public object Clone() + { + return new ProductDiscountInfoModel(Name, Key, DisplayName, DiscountedAmount, FromTime, ToTime); + } + + public override bool Equals(object obj) + { + return obj is ProductDiscountInfoModel other && Equals(other); + } + + protected bool Equals(ProductDiscountInfoModel other) + { + return Name == other.Name && + Key == other.Key && + DisplayName == other.DisplayName && + DiscountedAmount == other.DiscountedAmount && + Nullable.Equals(FromTime, other.FromTime) && + Nullable.Equals(ToTime, other.ToTime); + } + + public override int GetHashCode() + { + unchecked + { + var hashCode = Name.GetHashCode(); + hashCode = (hashCode * 397) ^ (Key != null ? Key.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ (DisplayName != null ? DisplayName.GetHashCode() : 0); + hashCode = (hashCode * 397) ^ DiscountedAmount.GetHashCode(); + hashCode = (hashCode * 397) ^ FromTime.GetHashCode(); + hashCode = (hashCode * 397) ^ ToTime.GetHashCode(); + return hashCode; + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductsErrorCodes.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductsErrorCodes.cs index 7f7baeca..71c0edea 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductsErrorCodes.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain.Shared/EasyAbp/EShop/Products/ProductsErrorCodes.cs @@ -16,5 +16,7 @@ public const string StaticProductCannotBeModified = "EasyAbp.EShop.Products:StaticProductCannotBeModified"; public const string StoreIsNotProductOwner = "EasyAbp.EShop.Products:StoreIsNotProductOwner"; public const string InventoryInsufficient = "EasyAbp.EShop.Products:InventoryInsufficient"; + public const string DiscountAmountOverflow = "EasyAbp.EShop.Products:DiscountAmountOverflow"; + public const string InvalidTimePeriod = "EasyAbp.EShop.Products:InvalidTimePeriod"; } } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductDiscountProvider.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductDiscountProvider.cs index 5e4b65c5..93f9bdef 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductDiscountProvider.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/IProductDiscountProvider.cs @@ -1,10 +1,8 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; -namespace EasyAbp.EShop.Products.Products +namespace EasyAbp.EShop.Products.Products; + +public interface IProductDiscountProvider { - public interface IProductDiscountProvider - { - Task GetDiscountedPriceAsync(Product product, ProductSku productSku, decimal currentPrice); - } + Task DiscountAsync(ProductDiscountContext context); } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/PriceDataModel.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/PriceDataModel.cs index f8168434..7bd90669 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/PriceDataModel.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/PriceDataModel.cs @@ -1,9 +1,37 @@ -namespace EasyAbp.EShop.Products.Products +using System; +using System.Collections.Generic; +using Volo.Abp.Timing; + +namespace EasyAbp.EShop.Products.Products; + +public class PriceDataModel : IHasFullDiscountsInfo { - public class PriceDataModel + public DateTime Now { get; } + + public decimal PriceWithoutDiscount { get; } + + /// + /// It's a sum of the amount of product discounts which in effect at the current time (this.). + /// + public decimal DiscountedAmount => this.GetProductDiscountsDiscountedAmount(Now); + + /// + /// It has been subtracted from the product discounts which in effect at the current time (this.). + /// + public decimal DiscountedPrice => PriceWithoutDiscount - DiscountedAmount; + + public List ProductDiscounts { get; } = new(); + + public List OrderDiscountPreviews { get; } = new(); + + public PriceDataModel(decimal priceWithoutDiscount, IClock clock) { - public decimal Price { get; set; } - - public decimal DiscountedPrice { get; set; } + if (PriceWithoutDiscount < decimal.Zero) + { + throw new OverflowException(); + } + + Now = clock.Now; + PriceWithoutDiscount = priceWithoutDiscount; } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductDiscountContext.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductDiscountContext.cs new file mode 100644 index 00000000..7bec21bb --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductDiscountContext.cs @@ -0,0 +1,19 @@ +using Volo.Abp.Timing; + +namespace EasyAbp.EShop.Products.Products; + +public class ProductDiscountContext +{ + public Product Product { get; } + + public ProductSku ProductSku { get; } + + public PriceDataModel PriceDataModel { get; } + + public ProductDiscountContext(Product product, ProductSku productSku, decimal priceFromPriceProvider, IClock clock) + { + Product = product; + ProductSku = productSku; + PriceDataModel = new PriceDataModel(priceFromPriceProvider, clock); + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs index 4f3dbf36..f15eeb4c 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductManager.cs @@ -272,19 +272,15 @@ namespace EasyAbp.EShop.Products.Products { var price = await _productPriceProvider.GetPriceAsync(product, productSku); - var discountedPrice = price; + var context = new ProductDiscountContext(product, productSku, price, Clock); // Todo: provider execution ordering. foreach (var provider in LazyServiceProvider.LazyGetService>()) { - discountedPrice = await provider.GetDiscountedPriceAsync(product, productSku, discountedPrice); + await provider.DiscountAsync(context); } - return new PriceDataModel - { - Price = price, - DiscountedPrice = discountedPrice - }; + return context.PriceDataModel; } } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductView.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductView.cs index 37b7fd54..035392fe 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductView.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.Domain/EasyAbp/EShop/Products/Products/ProductView.cs @@ -1,15 +1,15 @@ using System; +using System.Collections.Generic; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Products.Products { - public class ProductView : CreationAuditedAggregateRoot, - IProductBase, IHasProductGroupDisplayName, IMultiTenant + public class ProductView : CreationAuditedAggregateRoot, IProductView, IMultiTenant { public virtual Guid? TenantId { get; protected set; } - #region Properties of IProduct + #region Properties of IProductBase public virtual Guid StoreId { get; protected set; } @@ -43,10 +43,18 @@ namespace EasyAbp.EShop.Products.Products public virtual string ProductGroupDisplayName { get; protected set; } + public virtual List ProductDiscounts { get; protected set; } + + public virtual List OrderDiscountPreviews { get; protected set; } + public virtual decimal? MinimumPrice { get; protected set; } public virtual decimal? MaximumPrice { get; protected set; } + public virtual decimal? MinimumPriceWithoutDiscount { get; protected set; } + + public virtual decimal? MaximumPriceWithoutDiscount { get; protected set; } + public virtual long Sold { get; protected set; } protected ProductView() @@ -71,8 +79,12 @@ namespace EasyAbp.EShop.Products.Products string mediaResources, int displayOrder, string productGroupDisplayName, + List productDiscounts, + List orderDiscountPreviews, decimal? minimumPrice, decimal? maximumPrice, + decimal? minimumPriceWithoutDiscount, + decimal? maximumPriceWithoutDiscount, long sold ) : base(id) { @@ -93,8 +105,12 @@ namespace EasyAbp.EShop.Products.Products DisplayOrder = displayOrder; ProductGroupDisplayName = productGroupDisplayName; + ProductDiscounts = productDiscounts ?? new List(); + OrderDiscountPreviews = orderDiscountPreviews ?? new List(); MinimumPrice = minimumPrice; MaximumPrice = maximumPrice; + MinimumPriceWithoutDiscount = minimumPriceWithoutDiscount; + MaximumPriceWithoutDiscount = maximumPriceWithoutDiscount; Sold = sold; } @@ -103,10 +119,18 @@ namespace EasyAbp.EShop.Products.Products Sold = sold; } - public void SetPrices(decimal? minimumPrice, decimal? maximumPrice) + public void SetPrices(decimal? min, decimal? max, decimal? minWithoutDiscount, decimal? maxWithoutDiscount) { - MinimumPrice = minimumPrice; - MaximumPrice = maximumPrice; + MinimumPrice = min; + MaximumPrice = max; + MinimumPriceWithoutDiscount = minWithoutDiscount; + MaximumPriceWithoutDiscount = maxWithoutDiscount; + } + + public void SetDiscounts(IHasDiscountsInfo discountsInfo) + { + ProductDiscounts = discountsInfo.ProductDiscounts ?? new List(); + OrderDiscountPreviews = discountsInfo.OrderDiscountPreviews ?? new List(); } } } \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/EShopProductsEntityTypeBuilderExtensions.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/EShopProductsEntityTypeBuilderExtensions.cs deleted file mode 100644 index 2f3dcf71..00000000 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/EShopProductsEntityTypeBuilderExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using EasyAbp.EShop.Products.EntityFrameworkCore.AttributeOptionIds; -using EasyAbp.EShop.Products.Products; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; - -namespace EasyAbp.EShop.Products.EntityFrameworkCore; - -public static class EShopProductsEntityTypeBuilderExtensions -{ - public static void TryConfigureAttributeOptionIds(this EntityTypeBuilder b) - { - if (b.Metadata.ClrType.IsAssignableTo()) - { - b.Property(nameof(IHasAttributeOptionIds.AttributeOptionIds)) - .HasConversion() - .Metadata.SetValueComparer(new AttributeOptionIdsValueComparer()); - } - } -} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ProductsDbContext.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ProductsDbContext.cs index 68a6da95..593c613a 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ProductsDbContext.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ProductsDbContext.cs @@ -1,8 +1,10 @@ +using System.Collections.Generic; using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Categories; +using EasyAbp.EShop.Products.EntityFrameworkCore.ValueMappings; using EasyAbp.EShop.Products.ProductCategories; using EasyAbp.EShop.Products.ProductDetails; using EasyAbp.EShop.Products.ProductHistories; @@ -41,5 +43,15 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore builder.ConfigureEShopProducts(); } + + protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) + { + base.ConfigureConventions(configurationBuilder); + + configurationBuilder.Properties>() + .HaveConversion(); + configurationBuilder.Properties>() + .HaveConversion(); + } } } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ProductsDbContextModelCreatingExtensions.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ProductsDbContextModelCreatingExtensions.cs index 58db971a..d0d2a208 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ProductsDbContextModelCreatingExtensions.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ProductsDbContextModelCreatingExtensions.cs @@ -5,6 +5,7 @@ using EasyAbp.EShop.Products.ProductCategories; using EasyAbp.EShop.Products.Categories; using EasyAbp.EShop.Products.Products; using System; +using EasyAbp.EShop.Products.EntityFrameworkCore.ValueMappings; using EasyAbp.EShop.Products.ProductDetails; using Microsoft.EntityFrameworkCore; using Volo.Abp; @@ -133,7 +134,8 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore builder.Entity(b => { b.ToTable(options.TablePrefix + "ProductViews", options.Schema); - b.ConfigureByConvention(); + b.ConfigureByConvention(); + b.TryConfigureDiscountsInfo(); /* Configure more properties here */ @@ -141,6 +143,8 @@ namespace EasyAbp.EShop.Products.EntityFrameworkCore b.Property(x => x.MinimumPrice).HasColumnType("decimal(20,8)"); b.Property(x => x.MaximumPrice).HasColumnType("decimal(20,8)"); + b.Property(x => x.MinimumPriceWithoutDiscount).HasColumnType("decimal(20,8)"); + b.Property(x => x.MaximumPriceWithoutDiscount).HasColumnType("decimal(20,8)"); }); } } diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/AttributeOptionIds/AttributeOptionIdsValueComparer.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/AttributeOptionIdsValueComparer.cs similarity index 85% rename from modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/AttributeOptionIds/AttributeOptionIdsValueComparer.cs rename to modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/AttributeOptionIdsValueComparer.cs index 64aacd03..581c64e6 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/AttributeOptionIds/AttributeOptionIdsValueComparer.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/AttributeOptionIdsValueComparer.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore.ChangeTracking; -namespace EasyAbp.EShop.Products.EntityFrameworkCore.AttributeOptionIds; +namespace EasyAbp.EShop.Products.EntityFrameworkCore.ValueMappings; public class AttributeOptionIdsValueComparer : ValueComparer> { diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/AttributeOptionIds/AttributeOptionIdsValueConverter.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/AttributeOptionIdsValueConverter.cs similarity index 85% rename from modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/AttributeOptionIds/AttributeOptionIdsValueConverter.cs rename to modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/AttributeOptionIdsValueConverter.cs index 765b0869..8b279a5c 100644 --- a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/AttributeOptionIds/AttributeOptionIdsValueConverter.cs +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/AttributeOptionIdsValueConverter.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Text.Json; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -namespace EasyAbp.EShop.Products.EntityFrameworkCore.AttributeOptionIds; +namespace EasyAbp.EShop.Products.EntityFrameworkCore.ValueMappings; public class AttributeOptionIdsValueConverter : ValueConverter, string> { diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/DiscountsInfoValueComparer.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/DiscountsInfoValueComparer.cs new file mode 100644 index 00000000..9971331a --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/DiscountsInfoValueComparer.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using EasyAbp.EShop.Products.Products; +using Microsoft.EntityFrameworkCore.ChangeTracking; + +namespace EasyAbp.EShop.Products.EntityFrameworkCore.ValueMappings; + +public class ProductDiscountsInfoValueComparer : ValueComparer> +{ + public ProductDiscountsInfoValueComparer() + : base( + (d1, d2) => d1.SequenceEqual(d2), + d => d.Aggregate(0, (k, v) => HashCode.Combine(k, v.GetHashCode())), + d => d.Select(x => (ProductDiscountInfoModel)x.Clone()).ToList()) + { + } +} + +public class OrderDiscountPreviewsInfoValueComparer : ValueComparer> +{ + public OrderDiscountPreviewsInfoValueComparer() + : base( + (d1, d2) => d1.SequenceEqual(d2), + d => d.Aggregate(0, (k, v) => HashCode.Combine(k, v.GetHashCode())), + d => new List(d)) + { + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/DiscountsInfoValueConverter.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/DiscountsInfoValueConverter.cs new file mode 100644 index 00000000..49d2812e --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/DiscountsInfoValueConverter.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Text.Json; +using EasyAbp.EShop.Products.Products; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace EasyAbp.EShop.Products.EntityFrameworkCore.ValueMappings; + +public class ProductDiscountsInfoValueConverter : ValueConverter, string> +{ + public ProductDiscountsInfoValueConverter() : base( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null)) + { + } +} + +public class OrderDiscountPreviewsInfoValueConverter : ValueConverter, string> +{ + public OrderDiscountPreviewsInfoValueConverter() : base( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null)) + { + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/EShopProductsEntityTypeBuilderExtensions.cs b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/EShopProductsEntityTypeBuilderExtensions.cs new file mode 100644 index 00000000..c0fad94b --- /dev/null +++ b/modules/EasyAbp.EShop.Products/src/EasyAbp.EShop.Products.EntityFrameworkCore/EasyAbp/EShop/Products/EntityFrameworkCore/ValueMappings/EShopProductsEntityTypeBuilderExtensions.cs @@ -0,0 +1,31 @@ +using System; +using EasyAbp.EShop.Products.Products; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace EasyAbp.EShop.Products.EntityFrameworkCore.ValueMappings; + +public static class EShopProductsEntityTypeBuilderExtensions +{ + public static void TryConfigureAttributeOptionIds(this EntityTypeBuilder b) + { + if (b.Metadata.ClrType.IsAssignableTo()) + { + b.Property(nameof(IHasAttributeOptionIds.AttributeOptionIds)) + .HasConversion() + .Metadata.SetValueComparer(new AttributeOptionIdsValueComparer()); + } + } + + public static void TryConfigureDiscountsInfo(this EntityTypeBuilder b) + { + if (b.Metadata.ClrType.IsAssignableTo()) + { + b.Property(nameof(IHasDiscountsInfo.ProductDiscounts)) + .HasConversion() + .Metadata.SetValueComparer(new ProductDiscountsInfoValueComparer()); + b.Property(nameof(IHasDiscountsInfo.OrderDiscountPreviews)) + .HasConversion() + .Metadata.SetValueComparer(new OrderDiscountPreviewsInfoValueComparer()); + } + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/DemoProductDiscountProvider.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/DemoProductDiscountProvider.cs new file mode 100644 index 00000000..ab022954 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/DemoProductDiscountProvider.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Timing; + +namespace EasyAbp.EShop.Products.Products; + +public class DemoProductDiscountProvider : IProductDiscountProvider +{ + private readonly IClock _clock; + + public DemoProductDiscountProvider(IClock clock) + { + _clock = clock; + } + + public Task DiscountAsync(ProductDiscountContext context) + { + if (context.Product.Id != ProductsTestData.Product1Id || + context.ProductSku.Id != ProductsTestData.Product1Sku1Id) + { + return Task.CompletedTask; + } + + context.PriceDataModel.ProductDiscounts.AddRange(new List + { + // These should affect: + new("DemoDiscount", "1", "Demo Discount 1", 0.01m, null, null), + new("DemoDiscount", "2", "Demo Discount 2", 0.01m, _clock.Now.AddDays(-1), null), + new("DemoDiscount", "3", "Demo Discount 3", 0.01m, null, _clock.Now.AddDays(1)), + new("DemoDiscount", "4", "Demo Discount 4", 0.01m, _clock.Now.AddDays(-1), _clock.Now.AddDays(1)), + // These should not affect: 0.01m, + new("DemoDiscount", "5", "Demo Discount 5", 0.01m, null, _clock.Now.AddDays(-1)), + new("DemoDiscount", "6", "Demo Discount 6", 0.01m, _clock.Now.AddDays(1), null), + new("DemoDiscount", "7", "Demo Discount 7", 0.01m, _clock.Now.AddDays(1), _clock.Now.AddDays(2)), + }); + + context.PriceDataModel.OrderDiscountPreviews.AddRange(new List + { + new("DemoDiscount", "1", "Demo Discount 1", 0.01m, 0.01m, null, null), + new("DemoDiscount", "2", "Demo Discount 2", 0.01m, 0.01m, _clock.Now.AddDays(-1), _clock.Now.AddDays(1)), + }); + + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductDiscountTests.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductDiscountTests.cs new file mode 100644 index 00000000..46c61936 --- /dev/null +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductDiscountTests.cs @@ -0,0 +1,43 @@ +using System.Threading.Tasks; +using EasyAbp.EShop.Products.Products.Dtos; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace EasyAbp.EShop.Products.Products; + +public class ProductDiscountTests : ProductsApplicationTestBase +{ + protected override void AfterAddApplication(IServiceCollection services) + { + services.AddTransient(); + base.AfterAddApplication(services); + } + + [Fact] + public async Task Should_Get_Product_With_Discount() + { + var productAppService = GetRequiredService(); + + var product1 = await productAppService.GetAsync(ProductsTestData.Product1Id); + var sku1 = (ProductSkuDto)product1.GetSkuById(ProductsTestData.Product1Sku1Id); + var sku2 = (ProductSkuDto)product1.GetSkuById(ProductsTestData.Product1Sku2Id); + + sku1.Price.ShouldBe(1m - 0.01m * 4); + sku1.ProductDiscounts.Count.ShouldBe(7); + sku1.ProductDiscounts.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "1"); + sku1.ProductDiscounts.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "2"); + sku1.ProductDiscounts.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "3"); + sku1.ProductDiscounts.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "4"); + sku1.ProductDiscounts.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "5"); + sku1.ProductDiscounts.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "6"); + sku1.ProductDiscounts.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "7"); + sku1.OrderDiscountPreviews.Count.ShouldBe(2); + sku1.OrderDiscountPreviews.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "1"); + sku1.OrderDiscountPreviews.ShouldContain(x => x.Name == "DemoDiscount" && x.Key == "2"); + + sku2.Price.ShouldBe(2m); + sku2.ProductDiscounts.ShouldBeEmpty(); + sku2.OrderDiscountPreviews.ShouldBeEmpty(); + } +} \ No newline at end of file diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductViewAppServiceTests.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductViewAppServiceTests.cs index d631bf1e..1307721b 100644 --- a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductViewAppServiceTests.cs +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.Application.Tests/Products/ProductViewAppServiceTests.cs @@ -31,14 +31,14 @@ namespace EasyAbp.EShop.Products.Products var productDto = getListResult.Items.FirstOrDefault(x => x.Id == ProductsTestData.Product1Id); productDto.ShouldNotBeNull(); - productDto.MinimumPrice.ShouldBe(1m); - productDto.MaximumPrice.ShouldBe(3m); + productDto.MinimumPriceWithoutDiscount.ShouldBe(1m); + productDto.MaximumPriceWithoutDiscount.ShouldBe(3m); var getResult = await _productViewAppService.GetAsync(ProductsTestData.Product1Id); getResult.ShouldNotBeNull(); - getResult.MinimumPrice.ShouldBe(1m); - getResult.MaximumPrice.ShouldBe(3m); + getResult.MinimumPriceWithoutDiscount.ShouldBe(1m); + getResult.MaximumPriceWithoutDiscount.ShouldBe(3m); } diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.EntityFrameworkCore.Tests/EasyAbp.EShop.Products.EntityFrameworkCore.Tests.csproj b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.EntityFrameworkCore.Tests/EasyAbp.EShop.Products.EntityFrameworkCore.Tests.csproj index 84d97499..a96a0410 100644 --- a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.EntityFrameworkCore.Tests/EasyAbp.EShop.Products.EntityFrameworkCore.Tests.csproj +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.EntityFrameworkCore.Tests/EasyAbp.EShop.Products.EntityFrameworkCore.Tests.csproj @@ -7,11 +7,10 @@ - - + diff --git a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopProductsEntityFrameworkCoreTestModule.cs b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopProductsEntityFrameworkCoreTestModule.cs index 6ad07173..d81be9fe 100644 --- a/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopProductsEntityFrameworkCoreTestModule.cs +++ b/modules/EasyAbp.EShop.Products/test/EasyAbp.EShop.Products.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopProductsEntityFrameworkCoreTestModule.cs @@ -3,14 +3,16 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Products.EntityFrameworkCore { [DependsOn( typeof(ProductsTestBaseModule), - typeof(EShopProductsEntityFrameworkCoreModule) - )] + typeof(EShopProductsEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqliteModule) + )] public class EShopProductsEntityFrameworkCoreTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/modules/EasyAbp.EShop.Stores/test/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests.csproj b/modules/EasyAbp.EShop.Stores/test/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests.csproj index b1a8f66f..7b1f5765 100644 --- a/modules/EasyAbp.EShop.Stores/test/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests.csproj +++ b/modules/EasyAbp.EShop.Stores/test/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests.csproj @@ -7,11 +7,10 @@ - - + diff --git a/modules/EasyAbp.EShop.Stores/test/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopStoresEntityFrameworkCoreTestModule.cs b/modules/EasyAbp.EShop.Stores/test/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopStoresEntityFrameworkCoreTestModule.cs index 704f185b..fb6a879b 100644 --- a/modules/EasyAbp.EShop.Stores/test/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopStoresEntityFrameworkCoreTestModule.cs +++ b/modules/EasyAbp.EShop.Stores/test/EasyAbp.EShop.Stores.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopStoresEntityFrameworkCoreTestModule.cs @@ -3,14 +3,16 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; namespace EasyAbp.EShop.Stores.EntityFrameworkCore { [DependsOn( typeof(EShopStoresTestBaseModule), - typeof(EShopStoresEntityFrameworkCoreModule) - )] + typeof(EShopStoresEntityFrameworkCoreModule), + typeof(AbpEntityFrameworkCoreSqliteModule) + )] public class EShopStoresEntityFrameworkCoreTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/BasketItemDto.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/BasketItemDto.cs index 45d44aa0..6314bb23 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/BasketItemDto.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/BasketItemDto.cs @@ -1,15 +1,17 @@ using System; +using System.Collections.Generic; +using EasyAbp.EShop.Products.Products; using Volo.Abp.Application.Dtos; namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos { [Serializable] - public class BasketItemDto : ExtensibleAuditedEntityDto + public class BasketItemDto : ExtensibleAuditedEntityDto, IServerSideBasketItemInfo { public string BasketName { get; set; } public Guid UserId { get; set; } - + public Guid StoreId { get; set; } public Guid ProductId { get; set; } @@ -18,26 +20,28 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos public int Quantity { get; set; } + public decimal PriceWithoutDiscount { get; set; } + + public decimal TotalPriceWithoutDiscount { get; set; } + public string MediaResources { get; set; } public string ProductUniqueName { get; set; } - + public string ProductDisplayName { get; set; } public string SkuName { 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; } + + public List ProductDiscounts { get; set; } + + public List OrderDiscountPreviews { get; set; } } } \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/ClientSideBasketItemModel.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/ClientSideBasketItemModel.cs index 2256d63e..7b8bc1a6 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/ClientSideBasketItemModel.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/Dtos/ClientSideBasketItemModel.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using EasyAbp.EShop.Products.Products; using JetBrains.Annotations; using Volo.Abp.ObjectExtending; @@ -8,71 +10,80 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems.Dtos; public class ClientSideBasketItemModel : ExtensibleObject, IBasketItem { public Guid Id { get; set; } - + public string BasketName { get; set; } - + public int Quantity { get; set; } public Guid StoreId { get; set; } - + public Guid ProductId { get; set; } - + public string ProductUniqueName { get; set; } - + public string ProductDisplayName { get; set; } - + public Guid ProductSkuId { get; set; } - + public string SkuName { get; set; } - + public string SkuDescription { get; set; } - + public string MediaResources { get; set; } public string Currency { get; set; } - - public decimal UnitPrice { get; set; } - - public decimal TotalPrice { get; set; } - - public decimal TotalDiscount { get; set; } - + + public decimal PriceWithoutDiscount { get; set; } + + public decimal TotalPriceWithoutDiscount { get; set; } + + public List ProductDiscounts { get; set; } + + public List OrderDiscountPreviews { get; set; } + public int Inventory { get; set; } - + public bool IsInvalid { get; set; } + public ClientSideBasketItemModel() + { + } + public ClientSideBasketItemModel( Guid id, [NotNull] string basketName, Guid storeId, Guid productId, - Guid productSkuId) + Guid productSkuId, + List productDiscounts, + List orderDiscountPreviews) { Id = id; BasketName = basketName; StoreId = storeId; ProductId = productId; ProductSkuId = productSkuId; + ProductDiscounts = productDiscounts ?? new List(); + OrderDiscountPreviews = orderDiscountPreviews ?? new List(); } - + public void SetIsInvalid(bool isInvalid) { IsInvalid = isInvalid; } - public void UpdateProductData(int quantity, IProductData productData) + public void Update(int quantity, IProductData productData) { Quantity = quantity; - + MediaResources = productData.MediaResources; ProductUniqueName = productData.ProductUniqueName; ProductDisplayName = productData.ProductDisplayName; SkuName = productData.SkuName; SkuDescription = productData.SkuDescription; Currency = productData.Currency; - UnitPrice = productData.UnitPrice; - TotalPrice = productData.TotalPrice; - TotalDiscount = productData.TotalDiscount; + PriceWithoutDiscount = productData.PriceWithoutDiscount; + TotalPriceWithoutDiscount = productData.PriceWithoutDiscount * quantity; Inventory = productData.Inventory; } } \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductDataModel.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductDataModel.cs index 9563b2b1..39034892 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductDataModel.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application.Contracts/EasyAbp/EShop/Plugins/Baskets/BasketItems/ProductDataModel.cs @@ -1,25 +1,28 @@ -namespace EasyAbp.EShop.Plugins.Baskets.BasketItems +using System.Collections.Generic; +using EasyAbp.EShop.Products.Products; + +namespace EasyAbp.EShop.Plugins.Baskets.BasketItems { public class ProductDataModel : IProductData { public string MediaResources { get; set; } - + public string ProductUniqueName { get; set; } - + public string ProductDisplayName { get; set; } - + public string SkuName { 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 decimal PriceWithoutDiscount { get; set; } + + public List ProductDiscounts { get; set; } = new(); + + public List OrderDiscountPreviews { get; set; } = new(); + public int Inventory { get; set; } } } \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasicBasketItemProductInfoUpdater.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasicBasketItemProductInfoUpdater.cs index 7b257ac0..ff904e1a 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasicBasketItemProductInfoUpdater.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasicBasketItemProductInfoUpdater.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using EasyAbp.EShop.Products.Products; using EasyAbp.EShop.Products.Products.Dtos; @@ -35,7 +37,7 @@ public class BasicBasketItemProductInfoUpdater : IBasketItemProductInfoUpdater, return; } - item.UpdateProductData(targetQuantity, new ProductDataModel + item.Update(targetQuantity, new ProductDataModel { MediaResources = productSkuDto.MediaResources ?? productDto.MediaResources, ProductUniqueName = productDto.UniqueName, @@ -43,9 +45,9 @@ public class BasicBasketItemProductInfoUpdater : IBasketItemProductInfoUpdater, SkuName = productSkuDto.Name, SkuDescription = await ProductSkuDescriptionProvider.GenerateAsync(productDto, productSkuDto), Currency = productSkuDto.Currency, - UnitPrice = productSkuDto.DiscountedPrice, - TotalPrice = productSkuDto.DiscountedPrice * item.Quantity, - TotalDiscount = (productSkuDto.Price - productSkuDto.DiscountedPrice) * item.Quantity, + PriceWithoutDiscount = productSkuDto.PriceWithoutDiscount, + ProductDiscounts = productSkuDto.ProductDiscounts, + OrderDiscountPreviews = productSkuDto.OrderDiscountPreviews, Inventory = productSkuDto.Inventory }); diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItemAppService.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItemAppService.cs index f58bbea8..9bcb3eb9 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItemAppService.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Application/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItemAppService.cs @@ -179,7 +179,7 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems return await MapToGetOutputDtoAsync(item); } - var productSkuDto = productDto.FindSkuById(input.ProductSkuId); + var productSkuDto = (ProductSkuDto)productDto.FindSkuById(input.ProductSkuId); if (productSkuDto == null) { @@ -187,8 +187,9 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems } item = new BasketItem(GuidGenerator.Create(), CurrentTenant.Id, input.BasketName, CurrentUser.GetId(), - productDto.StoreId, input.ProductId, input.ProductSkuId); - + productDto.StoreId, input.ProductId, input.ProductSkuId, productSkuDto.ProductDiscounts, + productSkuDto.OrderDiscountPreviews); + input.MapExtraPropertiesTo(item); await UpdateProductDataAsync(input.Quantity, item, productDto); @@ -269,7 +270,7 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems var productDto = products[dto.ProductId]; - var productSkuDto = productDto.FindSkuById(dto.ProductSkuId); + var productSkuDto = (ProductSkuDto)productDto.FindSkuById(dto.ProductSkuId); if (productSkuDto == null) { @@ -278,8 +279,8 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems var id = dto.Id ?? GuidGenerator.Create(); - var item = new ClientSideBasketItemModel(id, dto.BasketName, productDto.StoreId, - dto.ProductId, dto.ProductSkuId); + var item = new ClientSideBasketItemModel(id, dto.BasketName, productDto.StoreId, dto.ProductId, + dto.ProductSkuId, productSkuDto.ProductDiscounts, productSkuDto.OrderDiscountPreviews); await UpdateProductDataAsync(dto.Quantity, item, productDto); diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp.EShop.Plugins.Baskets.Domain.Shared.csproj b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp.EShop.Plugins.Baskets.Domain.Shared.csproj index ce693f30..07beb6d1 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp.EShop.Plugins.Baskets.Domain.Shared.csproj +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp.EShop.Plugins.Baskets.Domain.Shared.csproj @@ -20,5 +20,9 @@ + + + + diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItem.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItem.cs index 15d13d5a..6b32199b 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItem.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItem.cs @@ -1,27 +1,8 @@ -using System; -using JetBrains.Annotations; -using Volo.Abp.Data; - namespace EasyAbp.EShop.Plugins.Baskets.BasketItems; -public interface IBasketItem : IProductData, IHasExtraProperties +public interface IBasketItem : IBasketItemInfo { - Guid Id { get; } - - [NotNull] - string BasketName { get; } - - Guid StoreId { get; } - - Guid ProductId { get; } - - Guid ProductSkuId { get; } - - int Quantity { get; } - - bool IsInvalid { get; } - void SetIsInvalid(bool isInvalid); - void UpdateProductData(int quantity, IProductData productData); + void Update(int quantity, IProductData productData); } \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItemInfo.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItemInfo.cs new file mode 100644 index 00000000..4922b72f --- /dev/null +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IBasketItemInfo.cs @@ -0,0 +1,28 @@ +using System; +using JetBrains.Annotations; +using Volo.Abp.Data; + +namespace EasyAbp.EShop.Plugins.Baskets.BasketItems; + +public interface IBasketItemInfo : IProductData, IHasExtraProperties +{ + Guid Id { get; } + + [NotNull] + string BasketName { get; } + + Guid StoreId { get; } + + Guid ProductId { get; } + + Guid ProductSkuId { get; } + + int Quantity { get; } + + /// + /// PriceWithoutDiscount * Quantity + /// + decimal TotalPriceWithoutDiscount { get; } + + bool IsInvalid { get; } +} \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IProductData.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IProductData.cs index 6692462e..367160f0 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IProductData.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IProductData.cs @@ -1,25 +1,21 @@ -namespace EasyAbp.EShop.Plugins.Baskets.BasketItems +using EasyAbp.EShop.Products.Products; + +namespace EasyAbp.EShop.Plugins.Baskets.BasketItems { - public interface IProductData + public interface IProductData : IHasFullDiscountsInfo { string MediaResources { get; } - + string ProductUniqueName { get; } - + string ProductDisplayName { get; } - + string SkuName { get; } - + string SkuDescription { get; } string Currency { get; } - - decimal UnitPrice { get; } - - decimal TotalPrice { get; } - - decimal TotalDiscount { get; } - + int Inventory { get; } } } \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IServerSideBasketItemInfo.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IServerSideBasketItemInfo.cs new file mode 100644 index 00000000..d1d67048 --- /dev/null +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/BasketItems/IServerSideBasketItemInfo.cs @@ -0,0 +1,8 @@ +using System; + +namespace EasyAbp.EShop.Plugins.Baskets.BasketItems; + +public interface IServerSideBasketItemInfo : IBasketItemInfo +{ + Guid UserId { get; } +} \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/EShopPluginsBasketsDomainSharedModule.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/EShopPluginsBasketsDomainSharedModule.cs index 2031e0ca..6cc857e7 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/EShopPluginsBasketsDomainSharedModule.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/EShopPluginsBasketsDomainSharedModule.cs @@ -1,6 +1,7 @@ using Volo.Abp.Modularity; using Volo.Abp.Localization; using EasyAbp.EShop.Plugins.Baskets.Localization; +using EasyAbp.EShop.Products; using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Validation; using Volo.Abp.Validation.Localization; @@ -9,7 +10,8 @@ using Volo.Abp.VirtualFileSystem; namespace EasyAbp.EShop.Plugins.Baskets { [DependsOn( - typeof(AbpValidationModule) + typeof(AbpValidationModule), + typeof(EShopProductsDomainSharedModule) )] public class EShopPluginsBasketsDomainSharedModule : AbpModule { diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/en.json b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/en.json index ba85b081..1ab1f79a 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/en.json +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/en.json @@ -12,17 +12,18 @@ "BasketItemProductId": "Product ID", "BasketItemProductSkuId": "Product SKU ID", "BasketItemQuantity": "Quantity", + "PriceWithoutDiscount": "Price without discount", + "TotalPriceWithoutDiscount": "Total price without discount", "BasketItemMediaResources": "Media resources", "BasketItemProductUniqueName": "Product unique name", "BasketItemProductDisplayName": "Product display name", "BasketItemSkuName": "SKU name", "BasketItemSkuDescription": "SKU description", "BasketItemCurrency": "Currency", - "BasketItemUnitPrice": "Unit price", - "BasketItemTotalPrice": "Total price", - "BasketItemTotalDiscount": "Total discount", "BasketItemInventory": "Inventory", "BasketItemIsInvalid": "Invalid", + "ProductDiscounts": "Product discounts", + "OrderDiscountPreviews": "Order discount previews", "CreateBasketItem": "New", "EditBasketItem": "Edit", "BasketItemDeletionConfirmationMessage": "Are you sure to delete the basket item {0}?", diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hans.json b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hans.json index 9d917b82..d33b0a16 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hans.json +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hans.json @@ -12,17 +12,18 @@ "BasketItemProductId": "商品 ID", "BasketItemProductSkuId": "商品 SKU ID", "BasketItemQuantity": "数量", + "PriceWithoutDiscount": "单价(不含折扣)", + "TotalPriceWithoutDiscount": "总价(不含折扣)", "BasketItemMediaResources": "多媒体资源", "BasketItemProductUniqueName": "商品编号", "BasketItemProductDisplayName": "商品名称", "BasketItemSkuName": "SKU 编号", "BasketItemSkuDescription": "SKU 描述", "BasketItemCurrency": "币种", - "BasketItemUnitPrice": "单价", - "BasketItemTotalPrice": "总价", - "BasketItemTotalDiscount": "总折扣", "BasketItemInventory": "库存数", "BasketItemIsInvalid": "是否不可用", + "ProductDiscounts": "商品折扣", + "OrderDiscountPreviews": "订单折扣(预览)", "CreateBasketItem": "新建", "EditBasketItem": "编辑", "BasketItemDeletionConfirmationMessage": "确认删除购物车项 {0}?", diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hant.json b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hant.json index 20e509a7..9e9d31ca 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hant.json +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain.Shared/EasyAbp/EShop/Plugins/Baskets/Localization/zh-Hant.json @@ -12,17 +12,18 @@ "BasketItemProductId": "商品 ID", "BasketItemProductSkuId": "商品 SKU ID", "BasketItemQuantity": "數量", + "PriceWithoutDiscount": "單價(不含折扣)", + "TotalPriceWithoutDiscount": "總價(不含折扣)", "BasketItemMediaResources": "多媒體資源", "BasketItemProductUniqueName": "商品編號", "BasketItemProductDisplayName": "商品名稱", "BasketItemSkuName": "SKU 編號", "BasketItemSkuDescription": "SKU 描述", "BasketItemCurrency": "幣種", - "BasketItemUnitPrice": "單價", - "BasketItemTotalPrice": "總價", - "BasketItemTotalDiscount": "總折扣", "BasketItemInventory": "庫存數", "BasketItemIsInvalid": "是否不可用", + "ProductDiscounts": "商品折扣", + "OrderDiscountPreviews": "訂單折扣(預覽)", "CreateBasketItem": "新建", "EditBasketItem": "編輯", "BasketItemDeletionConfirmationMessage": "確認刪除購物車項 {0}?", diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItem.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItem.cs index 4b567d7f..64c08444 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItem.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/BasketItems/BasketItem.cs @@ -1,32 +1,38 @@ using System; +using System.Collections.Generic; +using EasyAbp.EShop.Products.Products; using JetBrains.Annotations; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; namespace EasyAbp.EShop.Plugins.Baskets.BasketItems { - public class BasketItem : AuditedAggregateRoot, IBasketItem, IMultiTenant + public class BasketItem : AuditedAggregateRoot, IBasketItem, IServerSideBasketItemInfo, IMultiTenant { public virtual Guid? TenantId { get; protected set; } - + public virtual string BasketName { get; protected set; } - + 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; } - + public virtual int Quantity { get; protected set; } - + + public virtual decimal PriceWithoutDiscount { get; protected set; } + + public virtual decimal TotalPriceWithoutDiscount { get; protected set; } + [CanBeNull] public virtual string MediaResources { get; protected set; } - + [CanBeNull] public virtual string ProductUniqueName { get; protected set; } - + [NotNull] public virtual string ProductDisplayName { get; protected set; } @@ -38,21 +44,19 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems [NotNull] public virtual string Currency { get; protected set; } - - public virtual decimal UnitPrice { get; protected set; } - - 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; } + public virtual List ProductDiscounts { get; protected set; } + + public virtual List OrderDiscountPreviews { get; protected set; } + protected BasketItem() { } - + public BasketItem( Guid id, Guid? tenantId, @@ -60,7 +64,9 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems Guid userId, Guid storeId, Guid productId, - Guid productSkuId) : base(id) + Guid productSkuId, + List productDiscounts, + List orderDiscountPreviews) : base(id) { TenantId = tenantId; BasketName = basketName; @@ -68,21 +74,22 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems StoreId = storeId; ProductId = productId; ProductSkuId = productSkuId; + ProductDiscounts = productDiscounts ?? new List(); + OrderDiscountPreviews = orderDiscountPreviews ?? new List(); } - public void UpdateProductData(int quantity, IProductData productData) + public void Update(int quantity, IProductData productData) { Quantity = quantity; - + MediaResources = productData.MediaResources; ProductUniqueName = productData.ProductUniqueName; ProductDisplayName = productData.ProductDisplayName; SkuName = productData.SkuName; SkuDescription = productData.SkuDescription; Currency = productData.Currency; - UnitPrice = productData.UnitPrice; - TotalPrice = productData.TotalPrice; - TotalDiscount = productData.TotalDiscount; + PriceWithoutDiscount = productData.PriceWithoutDiscount; + TotalPriceWithoutDiscount = productData.PriceWithoutDiscount * quantity; Inventory = productData.Inventory; } @@ -91,4 +98,4 @@ namespace EasyAbp.EShop.Plugins.Baskets.BasketItems IsInvalid = isInvalid; } } -} +} \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/ProductUpdateRecorder.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/ProductUpdateRecorder.cs index c8d577f3..c07dc9bd 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/ProductUpdateRecorder.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Domain/EasyAbp/EShop/Plugins/Baskets/ProductUpdates/ProductUpdateRecorder.cs @@ -16,6 +16,8 @@ namespace EasyAbp.EShop.Plugins.Baskets.ProductUpdates IProductUpdateRecorder, IDistributedEventHandler>, IDistributedEventHandler, + // todo: while discount changed + // todo: manually refresh event ITransientDependency { private readonly IGuidGenerator _guidGenerator; diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContext.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContext.cs index e16f2ff1..c84889c6 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContext.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContext.cs @@ -1,8 +1,11 @@ +using System.Collections.Generic; using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using EasyAbp.EShop.Plugins.Baskets.BasketItems; +using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.ValueMappings; using EasyAbp.EShop.Plugins.Baskets.ProductUpdates; +using EasyAbp.EShop.Products.Products; namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore { @@ -15,10 +18,9 @@ namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore public DbSet BasketItems { get; set; } public DbSet ProductUpdates { get; set; } - public BasketsDbContext(DbContextOptions options) + public BasketsDbContext(DbContextOptions options) : base(options) { - } protected override void OnModelCreating(ModelBuilder builder) @@ -27,5 +29,15 @@ namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore builder.ConfigureEShopPluginsBaskets(); } + + protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) + { + base.ConfigureConventions(configurationBuilder); + + configurationBuilder.Properties>() + .HaveConversion(); + configurationBuilder.Properties>() + .HaveConversion(); + } } -} +} \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContextModelCreatingExtensions.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContextModelCreatingExtensions.cs index b30a1b00..9c68a46f 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContextModelCreatingExtensions.cs +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/BasketsDbContextModelCreatingExtensions.cs @@ -1,6 +1,8 @@ using EasyAbp.EShop.Plugins.Baskets.BasketItems; using System; +using EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.ValueMappings; using EasyAbp.EShop.Plugins.Baskets.ProductUpdates; +using EasyAbp.EShop.Products.Products; using Microsoft.EntityFrameworkCore; using Volo.Abp; using Volo.Abp.EntityFrameworkCore.Modeling; @@ -46,26 +48,26 @@ namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore builder.Entity(b => { b.ToTable(options.TablePrefix + "BasketItems", options.Schema); - b.ConfigureByConvention(); + b.ConfigureByConvention(); + b.TryConfigureDiscountsInfo(); /* 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)"); + b.Property(x => x.PriceWithoutDiscount).HasColumnType("decimal(20,8)"); + b.Property(x => x.TotalPriceWithoutDiscount).HasColumnType("decimal(20,8)"); }); builder.Entity(b => { b.ToTable(options.TablePrefix + "ProductUpdates", options.Schema); - b.ConfigureByConvention(); - + b.ConfigureByConvention(); + /* Configure more properties here */ b.HasIndex(x => x.ProductSkuId); }); } } -} +} \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/DiscountsInfoValueComparer.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/DiscountsInfoValueComparer.cs new file mode 100644 index 00000000..dbf5504a --- /dev/null +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/DiscountsInfoValueComparer.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using EasyAbp.EShop.Products.Products; +using Microsoft.EntityFrameworkCore.ChangeTracking; + +namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.ValueMappings; + +public class ProductDiscountsInfoValueComparer : ValueComparer> +{ + public ProductDiscountsInfoValueComparer() + : base( + (d1, d2) => d1.SequenceEqual(d2), + d => d.Aggregate(0, (k, v) => HashCode.Combine(k, v.GetHashCode())), + d => d.Select(x => (ProductDiscountInfoModel)x.Clone()).ToList()) + { + } +} + +public class OrderDiscountPreviewsInfoValueComparer : ValueComparer> +{ + public OrderDiscountPreviewsInfoValueComparer() + : base( + (d1, d2) => d1.SequenceEqual(d2), + d => d.Aggregate(0, (k, v) => HashCode.Combine(k, v.GetHashCode())), + d => new List(d)) + { + } +} \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/DiscountsInfoValueConverter.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/DiscountsInfoValueConverter.cs new file mode 100644 index 00000000..b9a7a2fe --- /dev/null +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/DiscountsInfoValueConverter.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.Text.Json; +using EasyAbp.EShop.Products.Products; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.ValueMappings; + +public class ProductDiscountsInfoValueConverter : ValueConverter, string> +{ + public ProductDiscountsInfoValueConverter() : base( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null)) + { + } +} + +public class OrderDiscountPreviewsInfoValueConverter : ValueConverter, string> +{ + public OrderDiscountPreviewsInfoValueConverter() : base( + v => JsonSerializer.Serialize(v, (JsonSerializerOptions)null), + v => JsonSerializer.Deserialize>(v, (JsonSerializerOptions)null)) + { + } +} \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/EShopProductsEntityTypeBuilderExtensions.cs b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/EShopProductsEntityTypeBuilderExtensions.cs new file mode 100644 index 00000000..1c8fa77e --- /dev/null +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore/EasyAbp/EShop/Plugins/Baskets/EntityFrameworkCore/ValueMappings/EShopProductsEntityTypeBuilderExtensions.cs @@ -0,0 +1,21 @@ +using System; +using EasyAbp.EShop.Products.Products; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace EasyAbp.EShop.Plugins.Baskets.EntityFrameworkCore.ValueMappings; + +public static class EShopProductsEntityTypeBuilderExtensions +{ + public static void TryConfigureDiscountsInfo(this EntityTypeBuilder b) + { + if (b.Metadata.ClrType.IsAssignableTo()) + { + b.Property(nameof(IHasDiscountsInfo.ProductDiscounts)) + .HasConversion() + .Metadata.SetValueComparer(new ProductDiscountsInfoValueComparer()); + b.Property(nameof(IHasDiscountsInfo.OrderDiscountPreviews)) + .HasConversion() + .Metadata.SetValueComparer(new OrderDiscountPreviewsInfoValueComparer()); + } + } +} \ No newline at end of file diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/Index.cshtml b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/Index.cshtml index 69247564..e2b8faa2 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/Index.cshtml +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/Index.cshtml @@ -54,15 +54,14 @@ @L["BasketItemProductId"] @L["BasketItemProductSkuId"] @L["BasketItemQuantity"] + @L["PriceWithoutDiscount"] + @L["TotalPriceWithoutDiscount"] @L["BasketItemMediaResources"] @L["BasketItemProductUniqueName"] @L["BasketItemProductDisplayName"] @L["BasketItemSkuName"] @L["BasketItemSkuDescription"] @L["BasketItemCurrency"] - @L["BasketItemUnitPrice"] - @L["BasketItemTotalPrice"] - @L["BasketItemTotalDiscount"] @L["BasketItemInventory"] @L["BasketItemIsInvalid"] diff --git a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.js b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.js index 950d55d2..6767b039 100644 --- a/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.js +++ b/plugins/Baskets/src/EasyAbp.EShop.Plugins.Baskets.Web/Pages/EShop/Plugins/Baskets/BasketItems/BasketItem/index.js @@ -57,15 +57,14 @@ $(function () { { data: "productId" }, { data: "productSkuId" }, { data: "quantity" }, + { data: "priceWithoutDiscount" }, + { data: "totalPriceWithoutDiscount" }, { data: "mediaResources" }, { data: "productUniqueName" }, { data: "productDisplayName" }, { data: "skuName" }, { data: "skuDescription" }, { data: "currency" }, - { data: "unitPrice" }, - { data: "totalPrice" }, - { data: "totalDiscount" }, { data: "inventory" }, { data: "isInvalid" }, ] diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20230408062955_ImplementedProductDiscounts.Designer.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20230408062955_ImplementedProductDiscounts.Designer.cs new file mode 100644 index 00000000..6adb4a9e --- /dev/null +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20230408062955_ImplementedProductDiscounts.Designer.cs @@ -0,0 +1,6421 @@ +// +using System; +using EShopSample.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; + +#nullable disable + +namespace EShopSample.Migrations +{ + [DbContext(typeof(EShopSampleDbContext))] + [Migration("20230408062955_ImplementedProductDiscounts")] + partial class ImplementedProductDiscounts + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("ProductVersion", "7.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DefaultPeriodUsable") + .HasColumnType("int"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Disabled") + .HasColumnType("bit"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EasyAbpBookingServiceAssetCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetOccupancies.AssetOccupancy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Asset") + .HasColumnType("nvarchar(max)"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OccupierName") + .HasColumnType("nvarchar(max)"); + + b.Property("OccupierUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("Date", "OccupierUserId"); + + b.HasIndex("Date", "AssetId", "StartingTime", "Duration"); + + b.ToTable("EasyAbpBookingServiceAssetOccupancies", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetOccupancyCounts.AssetOccupancyCount", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("Asset") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Date", "AssetId", "StartingTime", "Duration"); + + b.ToTable("EasyAbpBookingServiceAssetOccupancyCounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetPeriodSchemes.AssetPeriodScheme", b => + { + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Date", "AssetId"); + + b.ToTable("EasyAbpBookingServiceAssetPeriodSchemes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetSchedules.AssetSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("PeriodUsable") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Date", "AssetId", "PeriodSchemeId"); + + b.ToTable("EasyAbpBookingServiceAssetSchedules", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.Assets.Asset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("AssetDefinitionName") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DefaultPeriodUsable") + .HasColumnType("int"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Disabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Priority") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Volume") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpBookingServiceAssets", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.Period", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Duration") + .HasColumnType("time"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("StartingTime") + .HasColumnType("time"); + + b.HasKey("Id"); + + b.HasIndex("PeriodSchemeId"); + + b.ToTable("EasyAbpBookingServicePeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpBookingServicePeriodSchemes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CancellationReason") + .HasColumnType("nvarchar(max)"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderNumber") + .HasColumnType("nvarchar(450)"); + + b.Property("OrderStatus") + .HasColumnType("int"); + + b.Property("PaidTime") + .HasColumnType("datetime2"); + + b.Property("PaymentExpiration") + .HasColumnType("datetime2"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("ReducedInventoryAfterPaymentTime") + .HasColumnType("datetime2"); + + b.Property("ReducedInventoryAfterPlacingTime") + .HasColumnType("datetime2"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("OrderNumber") + .IsUnique() + .HasFilter("[OrderNumber] IS NOT NULL"); + + b.ToTable("EasyAbpEShopOrdersOrders", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderDiscount", b => + { + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("OrderLineId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Key") + .HasColumnType("nvarchar(450)"); + + b.Property("DiscountedAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("OrderId", "OrderLineId", "Name", "Key"); + + b.ToTable("EasyAbpEShopOrdersOrderDiscounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => + { + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Key") + .HasColumnType("nvarchar(450)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("Fee") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.HasKey("OrderId", "Name", "Key"); + + b.ToTable("EasyAbpEShopOrdersOrderExtraFees", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualTotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDetailModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductInventoryStrategy") + .HasColumnType("int"); + + b.Property("ProductModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductUniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundedQuantity") + .HasColumnType("int"); + + b.Property("SkuDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("SkuName") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("TotalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("EasyAbpEShopOrdersOrderLines", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PayeeAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPaymentsPayments", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.PaymentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("ItemKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ItemType") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpEShopPaymentsPaymentItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletedTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundPaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPaymentsRefunds", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PaymentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundId") + .HasColumnType("uniqueidentifier"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RefundId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderExtraFee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("Key") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundItemId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("RefundItemId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItemOrderExtraFees", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderLine", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("OrderLineId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundedQuantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RefundItemId"); + + b.ToTable("EasyAbpEShopPaymentsRefundItemOrderLines", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Baskets.BasketItems.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BasketName") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Inventory") + .HasColumnType("int"); + + b.Property("IsInvalid") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderDiscountPreviews") + .HasColumnType("nvarchar(max)"); + + b.Property("PriceWithoutDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDiscounts") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductUniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("SkuDescription") + .HasColumnType("nvarchar(max)"); + + b.Property("SkuName") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalPriceWithoutDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EasyAbpEShopPluginsBasketsBasketItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Baskets.ProductUpdates.ProductUpdate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ProductSkuId"); + + b.ToTable("EasyAbpEShopPluginsBasketsProductUpdates", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.GrantedStores.GrantedStore", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowAll") + .HasColumnType("bit"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingGrantedStores", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FromTime") + .HasColumnType("datetime2"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("ToTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategoryPeriod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductAssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAssetCategoryId"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetCategoryPeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FromTime") + .HasColumnType("datetime2"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PeriodSchemeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("ToTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssets", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAssetPeriod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("PeriodId") + .HasColumnType("uniqueidentifier"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductAssetId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAssetId"); + + b.ToTable("EasyAbpEShopPluginsBookingProductAssetPeriods", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConditionAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CouponType") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DiscountAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsUnscoped") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(max)"); + + b.Property("UsableBeginTime") + .HasColumnType("datetime2"); + + b.Property("UsableDuration") + .HasColumnType("time"); + + b.Property("UsableEndTime") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplates", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplateScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CouponTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("CouponTemplateId"); + + b.ToTable("EasyAbpEShopPluginsCouponsCouponTemplateScopes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.Coupons.Coupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponTemplateId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DiscountedAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("ExpirationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UsedTime") + .HasColumnType("datetime2"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsCouponsCoupons", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSalePlans.FlashSalePlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BeginTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EndTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSalePlans", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.FlashSales.FlashSaleResults.FlashSaleResult", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("PlanId") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .HasColumnType("nvarchar(max)"); + + b.Property("ReducedInventoryTime") + .HasColumnType("datetime2"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopPluginsFlashSalesFlashSaleResults", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EasyAbpEShopProductsCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductCategories.ProductCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CategoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopProductsProductCategories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductDetailHistories.ProductDetailHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedEntityData") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ModificationTime"); + + b.HasIndex("ProductDetailId"); + + b.ToTable("EasyAbpEShopProductsProductDetailHistories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductDetails.ProductDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopProductsProductDetails", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductHistories.ProductHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("SerializedEntityData") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ModificationTime"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductHistories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.ProductInventories.ProductInventory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Inventory") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductSkuId") + .HasColumnType("uniqueidentifier"); + + b.Property("Sold") + .HasColumnType("bigint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ProductSkuId"); + + b.ToTable("EasyAbpEShopProductsProductInventories", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("InventoryProviderName") + .HasColumnType("nvarchar(max)"); + + b.Property("InventoryStrategy") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("Overview") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UniqueName"); + + b.ToTable("EasyAbpEShopProductsProducts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductAttributes", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttributeOption", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ProductAttributeId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductAttributeId"); + + b.ToTable("EasyAbpEShopProductsProductAttributeOptions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductSku", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AttributeOptionIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("OrderMaxQuantity") + .HasColumnType("int"); + + b.Property("OrderMinQuantity") + .HasColumnType("int"); + + b.Property("OriginalPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("Price") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("EasyAbpEShopProductsProductSkus", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductView", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayOrder") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("InventoryProviderName") + .HasColumnType("nvarchar(max)"); + + b.Property("InventoryStrategy") + .HasColumnType("int"); + + b.Property("IsHidden") + .HasColumnType("bit"); + + b.Property("IsPublished") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("MaximumPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("MaximumPriceWithoutDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("MediaResources") + .HasColumnType("nvarchar(max)"); + + b.Property("MinimumPrice") + .HasColumnType("decimal(20,8)"); + + b.Property("MinimumPriceWithoutDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("OrderDiscountPreviews") + .HasColumnType("nvarchar(max)"); + + b.Property("Overview") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentExpireIn") + .HasColumnType("time"); + + b.Property("ProductDetailId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductDiscounts") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProductGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("Sold") + .HasColumnType("bigint"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UniqueName") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UniqueName"); + + b.ToTable("EasyAbpEShopProductsProductViews", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.StoreOwners.StoreOwner", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OwnerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("OwnerUserId", "StoreId") + .IsUnique(); + + b.ToTable("EasyAbpEShopStoresStoreOwners", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.Stores.Store", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopStoresStores", (string)null); + }); + + modelBuilder.Entity("EasyAbp.EShop.Stores.Transactions.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActionName") + .HasColumnType("nvarchar(max)"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OrderId") + .HasColumnType("uniqueidentifier"); + + b.Property("StoreId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TransactionType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpEShopStoresTransactions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.Payment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PayeeAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePayments", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.PaymentItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ActualPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("ItemKey") + .HasColumnType("nvarchar(max)"); + + b.Property("ItemType") + .HasColumnType("nvarchar(max)"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("OriginalPaymentAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingRefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServicePaymentItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.Accounts.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountGroupName") + .HasColumnType("nvarchar(max)"); + + b.Property("Balance") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockedBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("PendingTopUpPaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PendingWithdrawalAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("PendingWithdrawalRecordId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("EasyAbpPaymentServicePrepaymentAccounts", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.Transactions.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("AccountUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("ActionName") + .HasColumnType("nvarchar(max)"); + + b.Property("ChangedBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("OriginalBalance") + .HasColumnType("decimal(20,8)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("PaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TransactionType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("AccountUserId"); + + b.ToTable("EasyAbpPaymentServicePrepaymentTransactions", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.WithdrawalRecords.WithdrawalRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("CancellationTime") + .HasColumnType("datetime2"); + + b.Property("CompletionTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ResultErrorCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ResultErrorMessage") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("WithdrawalMethod") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePrepaymentWithdrawalRecords", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Prepayment.WithdrawalRequests.WithdrawalRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccountId") + .HasColumnType("uniqueidentifier"); + + b.Property("AccountUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Amount") + .HasColumnType("decimal(20,8)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsApproved") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ReviewTime") + .HasColumnType("datetime2"); + + b.Property("ReviewerUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServicePrepaymentWithdrawalRequests", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.Refund", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CanceledTime") + .HasColumnType("datetime2"); + + b.Property("CompletedTime") + .HasColumnType("datetime2"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Currency") + .HasColumnType("nvarchar(max)"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayReason") + .HasColumnType("nvarchar(max)"); + + b.Property("ExternalTradingCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundPaymentMethod") + .HasColumnType("nvarchar(max)"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("EasyAbpPaymentServiceRefunds", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.RefundItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("CustomerRemark") + .HasColumnType("nvarchar(max)"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("PaymentItemId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAmount") + .HasColumnType("decimal(20,8)"); + + b.Property("RefundId") + .HasColumnType("uniqueidentifier"); + + b.Property("StaffRemark") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("RefundId"); + + b.ToTable("EasyAbpPaymentServiceRefundItems", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.WeChatPay.PaymentRecords.PaymentRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AppId") + .HasColumnType("nvarchar(max)"); + + b.Property("Attach") + .HasColumnType("nvarchar(max)"); + + b.Property("BankType") + .HasColumnType("nvarchar(max)"); + + b.Property("CashFee") + .HasColumnType("int"); + + b.Property("CashFeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponCount") + .HasColumnType("int"); + + b.Property("CouponFee") + .HasColumnType("int"); + + b.Property("CouponFees") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeviceInfo") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ErrCodeDes") + .HasColumnType("nvarchar(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("IsSubscribe") + .HasColumnType("nvarchar(max)"); + + b.Property("MchId") + .HasColumnType("nvarchar(max)"); + + b.Property("Openid") + .HasColumnType("nvarchar(max)"); + + b.Property("OutTradeNo") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("ResultCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnMsg") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementTotalFee") + .HasColumnType("int"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TimeEnd") + .HasColumnType("nvarchar(max)"); + + b.Property("TotalFee") + .HasColumnType("int"); + + b.Property("TradeType") + .HasColumnType("nvarchar(max)"); + + b.Property("TransactionId") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServiceWeChatPayPaymentRecords", (string)null); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.WeChatPay.RefundRecords.RefundRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AppId") + .HasColumnType("nvarchar(max)"); + + b.Property("CashFee") + .HasColumnType("int"); + + b.Property("CashFeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("CashRefundFee") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CouponIds") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponRefundCount") + .HasColumnType("int"); + + b.Property("CouponRefundFee") + .HasColumnType("int"); + + b.Property("CouponRefundFees") + .HasColumnType("nvarchar(max)"); + + b.Property("CouponTypes") + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FeeType") + .HasColumnType("nvarchar(max)"); + + b.Property("MchId") + .HasColumnType("nvarchar(max)"); + + b.Property("OutRefundNo") + .HasColumnType("nvarchar(450)"); + + b.Property("OutTradeNo") + .HasColumnType("nvarchar(max)"); + + b.Property("PaymentId") + .HasColumnType("uniqueidentifier"); + + b.Property("RefundAccount") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundFee") + .HasColumnType("int"); + + b.Property("RefundId") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundRecvAccout") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundRequestSource") + .HasColumnType("nvarchar(max)"); + + b.Property("RefundStatus") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnCode") + .HasColumnType("nvarchar(max)"); + + b.Property("ReturnMsg") + .HasColumnType("nvarchar(max)"); + + b.Property("SettlementRefundFee") + .HasColumnType("int"); + + b.Property("SettlementTotalFee") + .HasColumnType("int"); + + b.Property("SuccessTime") + .HasColumnType("nvarchar(max)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TotalFee") + .HasColumnType("int"); + + b.Property("TransactionId") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("OutRefundNo"); + + b.HasIndex("PaymentId"); + + b.ToTable("EasyAbpPaymentServiceWeChatPayRefundRecords", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasColumnType("nvarchar(max)"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorTenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ImpersonatorTenantName"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("ImpersonatorUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ImpersonatorUserName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("TenantName"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsAbandoned") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false); + + b.Property("JobArgs") + .IsRequired() + .HasMaxLength(1048576) + .HasColumnType("nvarchar(max)"); + + b.Property("JobName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("LastTryTime") + .HasColumnType("datetime2"); + + b.Property("NextTryTime") + .HasColumnType("datetime2"); + + b.Property("Priority") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint") + .HasDefaultValue((byte)15); + + b.Property("TryCount") + .ValueGeneratedOnAdd() + .HasColumnType("smallint") + .HasDefaultValue((short)0); + + b.HasKey("Id"); + + b.HasIndex("IsAbandoned", "NextTryTime"); + + b.ToTable("AbpBackgroundJobs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowedProviders") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("DefaultValue") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("GroupName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("IsAvailableToHost") + .HasColumnType("bit"); + + b.Property("IsVisibleToClients") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ParentName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ValueType") + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("GroupName"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpFeatures", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureGroupDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpFeatureGroups", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpFeatureValues", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsActive") + .HasColumnType("bit") + .HasColumnName("IsActive"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AllowedAccessTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiResourceId", "Type"); + + b.ToTable("IdentityServerApiResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ApiResourceId", "Key", "Value"); + + b.ToTable("IdentityServerApiResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiResourceId", "Scope"); + + b.ToTable("IdentityServerApiResourceScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.Property("ApiResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.HasKey("ApiResourceId", "Type", "Value"); + + b.ToTable("IdentityServerApiResourceSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerApiScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.Property("ApiScopeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ApiScopeId", "Type"); + + b.ToTable("IdentityServerApiScopeClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.Property("ApiScopeId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ApiScopeId", "Key", "Value"); + + b.ToTable("IdentityServerApiScopeProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenLifetime") + .HasColumnType("int"); + + b.Property("AccessTokenType") + .HasColumnType("int"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("bit"); + + b.Property("AllowOfflineAccess") + .HasColumnType("bit"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("bit"); + + b.Property("AllowRememberConsent") + .HasColumnType("bit"); + + b.Property("AllowedIdentityTokenSigningAlgorithms") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("bit"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("bit"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("int"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("BackChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ClientClaimsPrefix") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsentLifetime") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DeviceCodeLifetime") + .HasColumnType("int"); + + b.Property("EnableLocalLogin") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("bit"); + + b.Property("FrontChannelLogoutUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("IdentityTokenLifetime") + .HasColumnType("int"); + + b.Property("IncludeJwtId") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LogoUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("PairWiseSubjectSalt") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ProtocolType") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("RefreshTokenExpiration") + .HasColumnType("int"); + + b.Property("RefreshTokenUsage") + .HasColumnType("int"); + + b.Property("RequireClientSecret") + .HasColumnType("bit"); + + b.Property("RequireConsent") + .HasColumnType("bit"); + + b.Property("RequirePkce") + .HasColumnType("bit"); + + b.Property("RequireRequestObject") + .HasColumnType("bit"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("int"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("bit"); + + b.Property("UserCodeType") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("UserSsoLifetime") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("IdentityServerClients", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Origin") + .HasMaxLength(150) + .HasColumnType("nvarchar(150)"); + + b.HasKey("ClientId", "Origin"); + + b.ToTable("IdentityServerClientCorsOrigins", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("GrantType") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.HasKey("ClientId", "GrantType"); + + b.ToTable("IdentityServerClientGrantTypes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Provider") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ClientId", "Provider"); + + b.ToTable("IdentityServerClientIdPRestrictions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("PostLogoutRedirectUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "PostLogoutRedirectUri"); + + b.ToTable("IdentityServerClientPostLogoutRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "Key", "Value"); + + b.ToTable("IdentityServerClientProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("RedirectUri") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("ClientId", "RedirectUri"); + + b.ToTable("IdentityServerClientRedirectUris", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Scope") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("ClientId", "Scope"); + + b.ToTable("IdentityServerClientScopes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.Property("ClientId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.HasKey("ClientId", "Type", "Value"); + + b.ToTable("IdentityServerClientSecrets", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Devices.DeviceFlowCodes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("DeviceCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UserCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("DeviceCode") + .IsUnique(); + + b.HasIndex("Expiration"); + + b.HasIndex("UserCode"); + + b.ToTable("IdentityServerDeviceFlowCodes", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Grants.PersistedGrant", b => + { + b.Property("Key") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ClientId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ConsumedTime") + .HasColumnType("datetime2"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Data") + .IsRequired() + .HasMaxLength(50000) + .HasColumnType("nvarchar(max)"); + + b.Property("Description") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Expiration") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("SessionId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("SubjectId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Key"); + + b.HasIndex("Expiration"); + + b.HasIndex("SubjectId", "ClientId", "Type"); + + b.HasIndex("SubjectId", "SessionId", "Type"); + + b.ToTable("IdentityServerPersistedGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("DisplayName") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Emphasize") + .HasColumnType("bit"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.ToTable("IdentityServerIdentityResources", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.Property("IdentityResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.HasKey("IdentityResourceId", "Type"); + + b.ToTable("IdentityServerIdentityResourceClaims", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.Property("IdentityResourceId") + .HasColumnType("uniqueidentifier"); + + b.Property("Key") + .HasMaxLength(250) + .HasColumnType("nvarchar(250)"); + + b.Property("Value") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)"); + + b.HasKey("IdentityResourceId", "Key", "Value"); + + b.ToTable("IdentityServerIdentityResourceProperties", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("GroupName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("MultiTenancySide") + .HasColumnType("tinyint"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ParentName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Providers") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("StateCheckers") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("GroupName"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpPermissions", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[TenantId] IS NOT NULL"); + + b.ToTable("AbpPermissionGrants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGroupDefinitionRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("AbpPermissionGroups", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey") + .IsUnique() + .HasFilter("[ProviderName] IS NOT NULL AND [ProviderKey] IS NOT NULL"); + + b.ToTable("AbpSettings", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityVersion") + .HasColumnType("int"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants", (string)null); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings", (string)null); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.HasOne("EasyAbp.BookingService.AssetCategories.AssetCategory", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetCategoryId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetCategoryId"); + + b1.ToTable("EasyAbpBookingServiceAssetCategories"); + + b1.WithOwner() + .HasForeignKey("AssetCategoryId"); + }); + + b.Navigation("Parent"); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetSchedules.AssetSchedule", b => + { + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetScheduleId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetScheduleId"); + + b1.ToTable("EasyAbpBookingServiceAssetSchedules"); + + b1.WithOwner() + .HasForeignKey("AssetScheduleId"); + }); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.Assets.Asset", b => + { + b.OwnsOne("EasyAbp.BookingService.TimeInAdvance", "TimeInAdvance", b1 => + { + b1.Property("AssetId") + .HasColumnType("uniqueidentifier"); + + b1.Property("MaxDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MaxTimespanInAdvance") + .HasColumnType("time"); + + b1.Property("MinDaysInAdvance") + .HasColumnType("int"); + + b1.Property("MinTimespanInAdvance") + .HasColumnType("time"); + + b1.HasKey("AssetId"); + + b1.ToTable("EasyAbpBookingServiceAssets"); + + b1.WithOwner() + .HasForeignKey("AssetId"); + }); + + b.Navigation("TimeInAdvance"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.Period", b => + { + b.HasOne("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", null) + .WithMany("Periods") + .HasForeignKey("PeriodSchemeId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderDiscount", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderDiscounts") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderExtraFees") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b => + { + b.HasOne("EasyAbp.EShop.Orders.Orders.Order", null) + .WithMany("OrderLines") + .HasForeignKey("OrderId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.PaymentItem", b => + { + b.HasOne("EasyAbp.EShop.Payments.Payments.Payment", null) + .WithMany("PaymentItems") + .HasForeignKey("PaymentId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.Refund", null) + .WithMany("RefundItems") + .HasForeignKey("RefundId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderExtraFee", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.RefundItem", null) + .WithMany("OrderExtraFees") + .HasForeignKey("RefundItemId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItemOrderLine", b => + { + b.HasOne("EasyAbp.EShop.Payments.Refunds.RefundItem", null) + .WithMany("OrderLines") + .HasForeignKey("RefundItemId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategoryPeriod", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", null) + .WithMany("Periods") + .HasForeignKey("ProductAssetCategoryId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAssetPeriod", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", null) + .WithMany("Periods") + .HasForeignKey("ProductAssetId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplateScope", b => + { + b.HasOne("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", null) + .WithMany("Scopes") + .HasForeignKey("CouponTemplateId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.HasOne("EasyAbp.EShop.Products.Categories.Category", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.Product", null) + .WithMany("ProductAttributes") + .HasForeignKey("ProductId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttributeOption", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.ProductAttribute", null) + .WithMany("ProductAttributeOptions") + .HasForeignKey("ProductAttributeId"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductSku", b => + { + b.HasOne("EasyAbp.EShop.Products.Products.Product", null) + .WithMany("ProductSkus") + .HasForeignKey("ProductId"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.PaymentItem", b => + { + b.HasOne("EasyAbp.PaymentService.Payments.Payment", null) + .WithMany("PaymentItems") + .HasForeignKey("PaymentId"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.RefundItem", b => + { + b.HasOne("EasyAbp.PaymentService.Refunds.Refund", null) + .WithMany("RefundItems") + .HasForeignKey("RefundId"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResourceSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiResources.ApiResource", null) + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScopeProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.ApiScopes.ApiScope", null) + .WithMany("Properties") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientCorsOrigin", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientGrantType", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientIdPRestriction", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientPostLogoutRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientRedirectUri", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientScope", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.ClientSecret", b => + { + b.HasOne("Volo.Abp.IdentityServer.Clients.Client", null) + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceClaim", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResourceProperty", b => + { + b.HasOne("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", null) + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EasyAbp.BookingService.AssetCategories.AssetCategory", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("EasyAbp.BookingService.PeriodSchemes.PeriodScheme", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.Order", b => + { + b.Navigation("OrderDiscounts"); + + b.Navigation("OrderExtraFees"); + + b.Navigation("OrderLines"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Payments.Payment", b => + { + b.Navigation("PaymentItems"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.Refund", b => + { + b.Navigation("RefundItems"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Payments.Refunds.RefundItem", b => + { + b.Navigation("OrderExtraFees"); + + b.Navigation("OrderLines"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssetCategories.ProductAssetCategory", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Booking.ProductAssets.ProductAsset", b => + { + b.Navigation("Periods"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Plugins.Coupons.CouponTemplates.CouponTemplate", b => + { + b.Navigation("Scopes"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Categories.Category", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.Product", b => + { + b.Navigation("ProductAttributes"); + + b.Navigation("ProductSkus"); + }); + + modelBuilder.Entity("EasyAbp.EShop.Products.Products.ProductAttribute", b => + { + b.Navigation("ProductAttributeOptions"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Payments.Payment", b => + { + b.Navigation("PaymentItems"); + }); + + modelBuilder.Entity("EasyAbp.PaymentService.Refunds.Refund", b => + { + b.Navigation("RefundItems"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiResources.ApiResource", b => + { + b.Navigation("Properties"); + + b.Navigation("Scopes"); + + b.Navigation("Secrets"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.ApiScopes.ApiScope", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.Clients.Client", b => + { + b.Navigation("AllowedCorsOrigins"); + + b.Navigation("AllowedGrantTypes"); + + b.Navigation("AllowedScopes"); + + b.Navigation("Claims"); + + b.Navigation("ClientSecrets"); + + b.Navigation("IdentityProviderRestrictions"); + + b.Navigation("PostLogoutRedirectUris"); + + b.Navigation("Properties"); + + b.Navigation("RedirectUris"); + }); + + modelBuilder.Entity("Volo.Abp.IdentityServer.IdentityResources.IdentityResource", b => + { + b.Navigation("Properties"); + + b.Navigation("UserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20230408062955_ImplementedProductDiscounts.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20230408062955_ImplementedProductDiscounts.cs new file mode 100644 index 00000000..88023650 --- /dev/null +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/20230408062955_ImplementedProductDiscounts.cs @@ -0,0 +1,109 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace EShopSample.Migrations +{ + /// + public partial class ImplementedProductDiscounts : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "TotalDiscount", + table: "EasyAbpEShopPluginsBasketsBasketItems"); + + migrationBuilder.RenameColumn( + name: "UnitPrice", + table: "EasyAbpEShopPluginsBasketsBasketItems", + newName: "TotalPriceWithoutDiscount"); + + migrationBuilder.RenameColumn( + name: "TotalPrice", + table: "EasyAbpEShopPluginsBasketsBasketItems", + newName: "PriceWithoutDiscount"); + + migrationBuilder.AddColumn( + name: "MaximumPriceWithoutDiscount", + table: "EasyAbpEShopProductsProductViews", + type: "decimal(20,8)", + nullable: true); + + migrationBuilder.AddColumn( + name: "MinimumPriceWithoutDiscount", + table: "EasyAbpEShopProductsProductViews", + type: "decimal(20,8)", + nullable: true); + + migrationBuilder.AddColumn( + name: "OrderDiscountPreviews", + table: "EasyAbpEShopProductsProductViews", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "ProductDiscounts", + table: "EasyAbpEShopProductsProductViews", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "OrderDiscountPreviews", + table: "EasyAbpEShopPluginsBasketsBasketItems", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "ProductDiscounts", + table: "EasyAbpEShopPluginsBasketsBasketItems", + type: "nvarchar(max)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "MaximumPriceWithoutDiscount", + table: "EasyAbpEShopProductsProductViews"); + + migrationBuilder.DropColumn( + name: "MinimumPriceWithoutDiscount", + table: "EasyAbpEShopProductsProductViews"); + + migrationBuilder.DropColumn( + name: "OrderDiscountPreviews", + table: "EasyAbpEShopProductsProductViews"); + + migrationBuilder.DropColumn( + name: "ProductDiscounts", + table: "EasyAbpEShopProductsProductViews"); + + migrationBuilder.DropColumn( + name: "OrderDiscountPreviews", + table: "EasyAbpEShopPluginsBasketsBasketItems"); + + migrationBuilder.DropColumn( + name: "ProductDiscounts", + table: "EasyAbpEShopPluginsBasketsBasketItems"); + + migrationBuilder.RenameColumn( + name: "TotalPriceWithoutDiscount", + table: "EasyAbpEShopPluginsBasketsBasketItems", + newName: "UnitPrice"); + + migrationBuilder.RenameColumn( + name: "PriceWithoutDiscount", + table: "EasyAbpEShopPluginsBasketsBasketItems", + newName: "TotalPrice"); + + migrationBuilder.AddColumn( + name: "TotalDiscount", + table: "EasyAbpEShopPluginsBasketsBasketItems", + type: "decimal(20,8)", + nullable: false, + defaultValue: 0m); + } + } +} diff --git a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs index 16fa461f..8c0bbf30 100644 --- a/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs +++ b/samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore/Migrations/EShopSampleDbContextModelSnapshot.cs @@ -1188,6 +1188,15 @@ namespace EShopSample.Migrations b.Property("MediaResources") .HasColumnType("nvarchar(max)"); + b.Property("OrderDiscountPreviews") + .HasColumnType("nvarchar(max)"); + + b.Property("PriceWithoutDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("ProductDiscounts") + .HasColumnType("nvarchar(max)"); + b.Property("ProductDisplayName") .HasColumnType("nvarchar(max)"); @@ -1216,13 +1225,7 @@ namespace EShopSample.Migrations .HasColumnType("uniqueidentifier") .HasColumnName("TenantId"); - b.Property("TotalDiscount") - .HasColumnType("decimal(20,8)"); - - b.Property("TotalPrice") - .HasColumnType("decimal(20,8)"); - - b.Property("UnitPrice") + b.Property("TotalPriceWithoutDiscount") .HasColumnType("decimal(20,8)"); b.Property("UserId") @@ -2590,12 +2593,21 @@ namespace EShopSample.Migrations b.Property("MaximumPrice") .HasColumnType("decimal(20,8)"); + b.Property("MaximumPriceWithoutDiscount") + .HasColumnType("decimal(20,8)"); + b.Property("MediaResources") .HasColumnType("nvarchar(max)"); b.Property("MinimumPrice") .HasColumnType("decimal(20,8)"); + b.Property("MinimumPriceWithoutDiscount") + .HasColumnType("decimal(20,8)"); + + b.Property("OrderDiscountPreviews") + .HasColumnType("nvarchar(max)"); + b.Property("Overview") .HasColumnType("nvarchar(max)"); @@ -2605,6 +2617,9 @@ namespace EShopSample.Migrations b.Property("ProductDetailId") .HasColumnType("uniqueidentifier"); + b.Property("ProductDiscounts") + .HasColumnType("nvarchar(max)"); + b.Property("ProductGroupDisplayName") .HasColumnType("nvarchar(max)"); diff --git a/samples/EShopSample/aspnet-core/test/EShopSample.EntityFrameworkCore.Tests/EShopSample.EntityFrameworkCore.Tests.csproj b/samples/EShopSample/aspnet-core/test/EShopSample.EntityFrameworkCore.Tests/EShopSample.EntityFrameworkCore.Tests.csproj index a818cec5..519ab28c 100644 --- a/samples/EShopSample/aspnet-core/test/EShopSample.EntityFrameworkCore.Tests/EShopSample.EntityFrameworkCore.Tests.csproj +++ b/samples/EShopSample/aspnet-core/test/EShopSample.EntityFrameworkCore.Tests/EShopSample.EntityFrameworkCore.Tests.csproj @@ -12,8 +12,7 @@ - - + diff --git a/samples/EShopSample/aspnet-core/test/EShopSample.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopSampleEntityFrameworkCoreTestModule.cs b/samples/EShopSample/aspnet-core/test/EShopSample.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopSampleEntityFrameworkCoreTestModule.cs index ad31d3df..c99a8d96 100644 --- a/samples/EShopSample/aspnet-core/test/EShopSample.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopSampleEntityFrameworkCoreTestModule.cs +++ b/samples/EShopSample/aspnet-core/test/EShopSample.EntityFrameworkCore.Tests/EntityFrameworkCore/EShopSampleEntityFrameworkCoreTestModule.cs @@ -5,14 +5,16 @@ using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; using Volo.Abp; using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore.Sqlite; using Volo.Abp.Modularity; namespace EShopSample.EntityFrameworkCore { [DependsOn( typeof(EShopSampleEntityFrameworkCoreModule), - typeof(EShopSampleTestBaseModule) - )] + typeof(EShopSampleTestBaseModule), + typeof(AbpEntityFrameworkCoreSqliteModule) + )] public class EShopSampleEntityFrameworkCoreTestModule : AbpModule { private SqliteConnection _sqliteConnection;