Browse Source

Introduce order extra fee

Resolve #106
pull/107/head
gdlcf88 5 years ago
parent
commit
08eca44cdf
  1. 2
      common.props
  2. 13
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/IOrderExtraFeeProvider.cs
  3. 20
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/NewOrderGenerator.cs
  4. 15
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderExtraFeeInfoModel.cs
  5. 12
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/DuplicateOrderExtraFeeException.cs
  6. 12
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/InvalidOrderExtraFeeException.cs
  7. 26
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/Order.cs
  8. 40
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderExtraFee.cs
  9. 1
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.EntityFrameworkCore/EasyAbp/EShop/Orders/EntityFrameworkCore/OrdersDbContext.cs
  10. 9
      modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.EntityFrameworkCore/EasyAbp/EShop/Orders/EntityFrameworkCore/OrdersDbContextModelCreatingExtensions.cs
  11. 4725
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20201127081415_AddedOrderExtraFee.Designer.cs
  12. 37
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20201127081415_AddedOrderExtraFee.cs
  13. 28
      samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/EShopSampleMigrationsDbContextModelSnapshot.cs

2
common.props

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>1.7.0</Version>
<Version>1.8.0</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>EasyAbp Team</Authors>

13
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/IOrderExtraFeeProvider.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Products.Products.Dtos;
namespace EasyAbp.EShop.Orders.Orders
{
public interface IOrderExtraFeeProvider
{
Task<OrderExtraFeeInfoModel> GetAsync(Guid customerUserId, CreateOrderDto input, Dictionary<Guid, ProductDto> productDict);
}
}

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

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using EasyAbp.EShop.Orders.Orders.Dtos;
using EasyAbp.EShop.Products.Products;
using EasyAbp.EShop.Products.Products.Dtos;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
@ -16,17 +17,20 @@ namespace EasyAbp.EShop.Orders.Orders
{
private readonly IGuidGenerator _guidGenerator;
private readonly ICurrentTenant _currentTenant;
private readonly IServiceProvider _serviceProvider;
private readonly IOrderNumberGenerator _orderNumberGenerator;
private readonly IProductSkuDescriptionProvider _productSkuDescriptionProvider;
public NewOrderGenerator(
IGuidGenerator guidGenerator,
ICurrentTenant currentTenant,
IServiceProvider serviceProvider,
IOrderNumberGenerator orderNumberGenerator,
IProductSkuDescriptionProvider productSkuDescriptionProvider)
{
_guidGenerator = guidGenerator;
_currentTenant = currentTenant;
_serviceProvider = serviceProvider;
_orderNumberGenerator = orderNumberGenerator;
_productSkuDescriptionProvider = productSkuDescriptionProvider;
}
@ -50,7 +54,6 @@ namespace EasyAbp.EShop.Orders.Orders
var productTotalPrice = orderLines.Select(x => x.TotalPrice).Sum();
// Todo: totalPrice may contain other fee.
var totalPrice = productTotalPrice;
var totalDiscount = orderLines.Select(x => x.TotalDiscount).Sum();
@ -68,6 +71,8 @@ namespace EasyAbp.EShop.Orders.Orders
input.MapExtraPropertiesTo(order, MappingPropertyDefinitionChecks.Destination);
await AddOrderExtraFeesAsync(order, customerUserId, input, productDict);
order.SetOrderLines(orderLines);
order.SetOrderNumber(await _orderNumberGenerator.CreateAsync(order));
@ -75,6 +80,19 @@ namespace EasyAbp.EShop.Orders.Orders
return order;
}
protected virtual async Task AddOrderExtraFeesAsync(Order order, Guid customerUserId,
CreateOrderDto input, Dictionary<Guid, ProductDto> productDict)
{
var providers = _serviceProvider.GetServices<IOrderExtraFeeProvider>();
foreach (var provider in providers)
{
var infoModel = await provider.GetAsync(customerUserId, input, productDict);
order.AddOrderExtraFee(infoModel.Fee, infoModel.Name, infoModel.Key);
}
}
protected virtual async Task<OrderLine> GenerateOrderLineAsync(CreateOrderDto input,
CreateOrderLineDto inputOrderLine, Dictionary<Guid, ProductDto> productDict)
{

15
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Application/EasyAbp/EShop/Orders/Orders/OrderExtraFeeInfoModel.cs

@ -0,0 +1,15 @@
using JetBrains.Annotations;
namespace EasyAbp.EShop.Orders.Orders
{
public class OrderExtraFeeInfoModel
{
[NotNull]
public string Name { get; set; }
[CanBeNull]
public string Key { get; set; }
public decimal Fee { get; set; }
}
}

12
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/DuplicateOrderExtraFeeException.cs

@ -0,0 +1,12 @@
using Volo.Abp;
namespace EasyAbp.EShop.Orders.Orders
{
public class DuplicateOrderExtraFeeException : BusinessException
{
public DuplicateOrderExtraFeeException(string extraFeeName, string extraFeeKey)
: base("DuplicateOrderExtraFee", $"The extra fee {extraFeeName} (key: {extraFeeKey}) is existed.")
{
}
}
}

12
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/InvalidOrderExtraFeeException.cs

@ -0,0 +1,12 @@
using Volo.Abp;
namespace EasyAbp.EShop.Orders.Orders
{
public class InvalidOrderExtraFeeException : BusinessException
{
public InvalidOrderExtraFeeException(decimal extraFee)
: base("InvalidExtraFee", $"The extra fee {extraFee} is invalid.")
{
}
}
}

26
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/Order.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using EasyAbp.EShop.Stores.Stores;
using System.Linq;
using JetBrains.Annotations;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
@ -10,6 +11,8 @@ namespace EasyAbp.EShop.Orders.Orders
{
public class Order : FullAuditedAggregateRoot<Guid>, IOrder, IMultiTenant
{
public const string ExtraFeeListPropertyName = "ExtraFeeList";
public virtual Guid? TenantId { get; protected set; }
public virtual Guid StoreId { get; protected set; }
@ -56,6 +59,8 @@ namespace EasyAbp.EShop.Orders.Orders
public virtual DateTime? ReducedInventoryAfterPaymentTime { get; protected set; }
public virtual List<OrderLine> OrderLines { get; protected set; }
public virtual List<OrderExtraFee> OrderExtraFees { get; protected set; }
protected Order()
{
@ -88,6 +93,7 @@ namespace EasyAbp.EShop.Orders.Orders
OrderStatus = OrderStatus.Pending;
OrderLines = new List<OrderLine>();
OrderExtraFees = new List<OrderExtraFee>();
}
public void SetOrderNumber([NotNull] string orderNumber)
@ -179,5 +185,25 @@ namespace EasyAbp.EShop.Orders.Orders
throw new DiscountAmountOverflowException();
}
}
public void AddOrderExtraFee(decimal extraFee, [NotNull] string extraFeeName, [CanBeNull] string extraFeeKey)
{
if (extraFee <= decimal.Zero)
{
throw new InvalidOrderExtraFeeException(extraFee);
}
var orderExtraFee = new OrderExtraFee(Id, extraFeeName, extraFeeKey, extraFee);
if (OrderExtraFees.Any(x => x.EntityEquals(orderExtraFee)))
{
throw new DuplicateOrderExtraFeeException(extraFeeName, extraFeeKey);
}
OrderExtraFees.Add(orderExtraFee);
TotalPrice += extraFee;
ActualTotalPrice += extraFee;
}
}
}

40
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.Domain/EasyAbp/EShop/Orders/Orders/OrderExtraFee.cs

@ -0,0 +1,40 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Domain.Entities;
namespace EasyAbp.EShop.Orders.Orders
{
public class OrderExtraFee : Entity
{
public virtual Guid OrderId { get; protected set; }
[NotNull]
public virtual string Name { get; protected set; }
[CanBeNull]
public virtual string Key { get; protected set; }
public virtual decimal Fee { get; protected set; }
protected OrderExtraFee()
{
}
public OrderExtraFee(
Guid orderId,
[NotNull] string name,
[CanBeNull] string key,
decimal fee)
{
OrderId = orderId;
Name = name;
Key = key;
Fee = fee;
}
public override object[] GetKeys()
{
return new object[] {OrderId, Name, Key};
}
}
}

1
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.EntityFrameworkCore/EasyAbp/EShop/Orders/EntityFrameworkCore/OrdersDbContext.cs

@ -13,6 +13,7 @@ namespace EasyAbp.EShop.Orders.EntityFrameworkCore
*/
public DbSet<Order> Orders { get; set; }
public DbSet<OrderLine> OrderLines { get; set; }
public DbSet<OrderExtraFee> OrderExtraFees { get; set; }
public OrdersDbContext(DbContextOptions<OrdersDbContext> options)
: base(options)

9
modules/EasyAbp.EShop.Orders/src/EasyAbp.EShop.Orders.EntityFrameworkCore/EasyAbp/EShop/Orders/EntityFrameworkCore/OrdersDbContextModelCreatingExtensions.cs

@ -65,6 +65,15 @@ namespace EasyAbp.EShop.Orders.EntityFrameworkCore
b.Property(x => x.UnitPrice).HasColumnType("decimal(20,8)");
b.Property(x => x.RefundAmount).HasColumnType("decimal(20,8)");
});
builder.Entity<OrderExtraFee>(b =>
{
b.ToTable(options.TablePrefix + "OrderExtraFees", options.Schema);
b.ConfigureByConvention();
/* Configure more properties here */
b.Property(x => x.Fee).HasColumnType("decimal(20,8)");
b.HasKey(x => new {x.OrderId, x.Name, x.Key});
});
}
}
}

4725
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20201127081415_AddedOrderExtraFee.Designer.cs

File diff suppressed because it is too large

37
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/20201127081415_AddedOrderExtraFee.cs

@ -0,0 +1,37 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EShopSample.Migrations
{
public partial class AddedOrderExtraFee : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "EasyAbpEShopOrdersOrderExtraFees",
columns: table => new
{
OrderId = table.Column<Guid>(nullable: false),
Name = table.Column<string>(nullable: false),
Key = table.Column<string>(nullable: false),
Fee = table.Column<decimal>(type: "decimal(20,8)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_EasyAbpEShopOrdersOrderExtraFees", x => new { x.OrderId, x.Name, x.Key });
table.ForeignKey(
name: "FK_EasyAbpEShopOrdersOrderExtraFees_EasyAbpEShopOrdersOrders_OrderId",
column: x => x.OrderId,
principalTable: "EasyAbpEShopOrdersOrders",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "EasyAbpEShopOrdersOrderExtraFees");
}
}
}

28
samples/EShopSample/aspnet-core/src/EShopSample.EntityFrameworkCore.DbMigrations/Migrations/EShopSampleMigrationsDbContextModelSnapshot.cs

@ -137,6 +137,25 @@ namespace EShopSample.Migrations
b.ToTable("EasyAbpEShopOrdersOrders");
});
modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderExtraFee", b =>
{
b.Property<Guid>("OrderId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.HasColumnType("nvarchar(450)");
b.Property<string>("Key")
.HasColumnType("nvarchar(450)");
b.Property<decimal>("Fee")
.HasColumnType("decimal(20,8)");
b.HasKey("OrderId", "Name", "Key");
b.ToTable("EasyAbpEShopOrdersOrderExtraFees");
});
modelBuilder.Entity("EasyAbp.EShop.Orders.Orders.OrderLine", b =>
{
b.Property<Guid>("Id")
@ -4363,6 +4382,15 @@ namespace EShopSample.Migrations
b.ToTable("AbpTenantConnectionStrings");
});
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)

Loading…
Cancel
Save