mirror of https://github.com/EasyAbp/EShop.git
115 changed files with 4580 additions and 203 deletions
@ -1,19 +0,0 @@ |
|||
using EasyAbp.EShop.Orders.Localization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Authorization |
|||
{ |
|||
public class OrdersPermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
//var moduleGroup = context.AddGroup(OrdersPermissions.GroupName, L("Permission:Orders"));
|
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<OrdersResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
using Volo.Abp.Reflection; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Authorization |
|||
{ |
|||
public class OrdersPermissions |
|||
{ |
|||
public const string GroupName = "EasyAbp.EShop.Orders"; |
|||
|
|||
public static string[] GetAll() |
|||
{ |
|||
return ReflectionHelper.GetPublicConstantsRecursively(typeof(OrdersPermissions)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using EasyAbp.EShop.Orders.Localization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Authorization |
|||
{ |
|||
public class OrdersPermissionDefinitionProvider : PermissionDefinitionProvider |
|||
{ |
|||
public override void Define(IPermissionDefinitionContext context) |
|||
{ |
|||
var moduleGroup = context.AddGroup(OrdersPermissions.GroupName, L("Permission:Orders")); |
|||
|
|||
var order = moduleGroup.AddPermission(OrdersPermissions.Orders.Default, L("Permission:Product")); |
|||
order.AddChild(OrdersPermissions.Orders.Manage, L("Permission:Manage")); |
|||
order.AddChild(OrdersPermissions.Orders.CrossStore, L("Permission:CrossStore")); |
|||
order.AddChild(OrdersPermissions.Orders.Create, L("Permission:Create")); |
|||
order.AddChild(OrdersPermissions.Orders.ConfirmReceipt, L("Permission:ConfirmReceipt")); |
|||
order.AddChild(OrdersPermissions.Orders.RequestCancellation, L("Permission:RequestCancellation")); |
|||
order.AddChild(OrdersPermissions.Orders.Cancel, L("Permission:Cancel")); |
|||
} |
|||
|
|||
private static LocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<OrdersResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
using Volo.Abp.Reflection; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Authorization |
|||
{ |
|||
public class OrdersPermissions |
|||
{ |
|||
public const string GroupName = "EasyAbp.EShop.Orders"; |
|||
|
|||
public class Orders |
|||
{ |
|||
public const string Default = GroupName + ".Order"; |
|||
public const string Manage = Default + ".Manage"; |
|||
public const string CrossStore = Default + ".CrossStore"; |
|||
public const string Create = Default + ".Create"; |
|||
public const string ConfirmReceipt = Default + ".ConfirmReceipt"; |
|||
public const string RequestCancellation = Default + ".RequestCancellation"; |
|||
public const string Cancel = Default + ".Cancel"; |
|||
} |
|||
|
|||
public static string[] GetAll() |
|||
{ |
|||
return ReflectionHelper.GetPublicConstantsRecursively(typeof(OrdersPermissions)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Linq; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders.Dtos |
|||
{ |
|||
public class CreateOrderDto : IValidatableObject |
|||
{ |
|||
[DisplayName("OrderStoreId")] |
|||
public Guid StoreId { get; set; } |
|||
|
|||
[DisplayName("OrderCustomerRemark")] |
|||
public string CustomerRemark { get; set; } |
|||
|
|||
[DisplayName("OrderLine")] |
|||
public List<CreateOrderLineDto> OrderLines { get; set; } |
|||
|
|||
[DisplayName("OrderExtraProperties")] |
|||
public Dictionary<string, object> ExtraProperties { get; set; } |
|||
|
|||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) |
|||
{ |
|||
if (OrderLines.Select(orderLine => orderLine.Quantity).Sum() <= 0) |
|||
{ |
|||
yield return new ValidationResult( |
|||
"Total quantity should be greater than 0.", |
|||
new[] { "OrderLines" } |
|||
); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders.Dtos |
|||
{ |
|||
public class CreateOrderLineDto |
|||
{ |
|||
[DisplayName("OrderLineProductId")] |
|||
public Guid ProductId { get; set; } |
|||
|
|||
[DisplayName("OrderLineProductSkuId")] |
|||
public Guid ProductSkuId { get; set; } |
|||
|
|||
[DisplayName("OrderLineQuantity")] |
|||
public int Quantity { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders.Dtos |
|||
{ |
|||
public class GetOrderListDto : PagedAndSortedResultRequestDto |
|||
{ |
|||
public Guid? StoreId { get; set; } |
|||
|
|||
public Guid? CustomerUserId { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders.Dtos |
|||
{ |
|||
public class OrderDto : ExtensibleFullAuditedEntityDto<Guid> |
|||
{ |
|||
public Guid StoreId { get; set; } |
|||
|
|||
public Guid CustomerUserId { get; set; } |
|||
|
|||
public OrderStatus OrderStatus { get; set; } |
|||
|
|||
public string Currency { get; set; } |
|||
|
|||
public decimal ProductTotalPrice { get; set; } |
|||
|
|||
public decimal TotalDiscount { get; set; } |
|||
|
|||
public decimal TotalPrice { get; set; } |
|||
|
|||
public decimal RefundedAmount { get; set; } |
|||
|
|||
public string CustomerRemark { get; set; } |
|||
|
|||
public string StaffRemark { get; set; } |
|||
|
|||
public DateTime? PaidTime { get; set; } |
|||
|
|||
public DateTime? CompletionTime { get; set; } |
|||
|
|||
public DateTime? CancelledTime { get; set; } |
|||
|
|||
public DateTime? ReducedInventoryAfterPlacingTime { get; set; } |
|||
|
|||
public DateTime? ReducedInventoryAfterPaymentTime { get; set; } |
|||
|
|||
public List<OrderLineDto> OrderLines { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders.Dtos |
|||
{ |
|||
public class OrderLineDto : FullAuditedEntityDto<Guid> |
|||
{ |
|||
public Guid ProductId { get; set; } |
|||
|
|||
public Guid ProductSkuId { get; set; } |
|||
|
|||
public DateTime ProductModificationTime { get; set; } |
|||
|
|||
public DateTime ProductDetailModificationTime { get; set; } |
|||
|
|||
public string ProductName { 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 int Quantity { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using EasyAbp.EShop.Orders.Orders.Dtos; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public interface IOrderAppService : |
|||
ICrudAppService< |
|||
OrderDto, |
|||
Guid, |
|||
GetOrderListDto, |
|||
CreateOrderDto, |
|||
CreateOrderDto> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -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 INewOrderGenerator |
|||
{ |
|||
Task<Order> GenerateAsync(CreateOrderDto input, Dictionary<Guid, ProductDto> productDict); |
|||
} |
|||
} |
|||
@ -0,0 +1,107 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Orders.Orders.Dtos; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Guids; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class NewOrderGenerator : INewOrderGenerator, ITransientDependency |
|||
{ |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
private readonly ICurrentTenant _currentTenant; |
|||
private readonly ICurrentUser _currentUser; |
|||
private readonly IJsonSerializer _jsonSerializer; |
|||
|
|||
public NewOrderGenerator( |
|||
IGuidGenerator guidGenerator, |
|||
ICurrentTenant currentTenant, |
|||
ICurrentUser currentUser, |
|||
IJsonSerializer jsonSerializer) |
|||
{ |
|||
_guidGenerator = guidGenerator; |
|||
_currentTenant = currentTenant; |
|||
_currentUser = currentUser; |
|||
_jsonSerializer = jsonSerializer; |
|||
} |
|||
|
|||
public virtual async Task<Order> GenerateAsync(CreateOrderDto input, Dictionary<Guid, ProductDto> productDict) |
|||
{ |
|||
var orderLines = new List<OrderLine>(); |
|||
|
|||
foreach (var orderLine in input.OrderLines) |
|||
{ |
|||
orderLines.Add(await GenerateNewOrderLineAsync(orderLine, productDict)); |
|||
} |
|||
|
|||
var productTotalPrice = orderLines.Select(x => x.TotalPrice).Sum(); |
|||
|
|||
var order = new Order( |
|||
id: _guidGenerator.Create(), |
|||
tenantId: _currentTenant.Id, |
|||
storeId: input.StoreId, |
|||
customerUserId: _currentUser.GetId(), |
|||
currency: await GetStoreCurrencyAsync(input.StoreId), |
|||
productTotalPrice: productTotalPrice, |
|||
totalDiscount: orderLines.Select(x => x.TotalDiscount).Sum(), |
|||
totalPrice: productTotalPrice, |
|||
refundedAmount: 0, |
|||
customerRemark: input.CustomerRemark); |
|||
|
|||
order.SetOrderLines(orderLines); |
|||
|
|||
return order; |
|||
} |
|||
|
|||
protected virtual async Task<OrderLine> GenerateNewOrderLineAsync(CreateOrderLineDto input, Dictionary<Guid, ProductDto> productDict) |
|||
{ |
|||
var product = productDict[input.ProductId]; |
|||
var productSku = product.ProductSkus.Single(x => x.Id == input.ProductSkuId); |
|||
|
|||
return new OrderLine( |
|||
id: _guidGenerator.Create(), |
|||
productId: product.Id, |
|||
productSkuId: productSku.Id, |
|||
productModificationTime: product.LastModificationTime ?? product.CreationTime, |
|||
productDetailModificationTime: productSku.LastModificationTime ?? productSku.CreationTime, |
|||
productName: product.DisplayName, |
|||
skuDescription: await GenerateSkuDescriptionAsync(product, productSku), |
|||
mediaResources: product.MediaResources, |
|||
currency: productSku.Currency, |
|||
unitPrice: productSku.Price, |
|||
totalPrice: productSku.Price * input.Quantity, |
|||
totalDiscount: 0, |
|||
quantity: input.Quantity |
|||
); |
|||
} |
|||
|
|||
protected virtual Task<string> GenerateSkuDescriptionAsync(ProductDto product, ProductSkuDto productSku) |
|||
{ |
|||
var attributeOptionIds = _jsonSerializer.Deserialize<Guid[]>(productSku.SerializedAttributeOptionIds); |
|||
|
|||
var names = new Collection<string[]>(); |
|||
|
|||
foreach (var attributeOptionId in attributeOptionIds) |
|||
{ |
|||
names.Add(product.ProductAttributes.SelectMany( |
|||
attribute => attribute.ProductAttributeOptions.Where(option => option.Id == attributeOptionId), |
|||
(attribute, option) => new [] {attribute.DisplayName, option.DisplayName}).Single()); |
|||
} |
|||
|
|||
return Task.FromResult(_jsonSerializer.Serialize(names)); |
|||
} |
|||
|
|||
protected virtual Task<string> GetStoreCurrencyAsync(Guid storeId) |
|||
{ |
|||
// Todo: Get real store currency configuration.
|
|||
return Task.FromResult("CNY"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,141 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Orders.Authorization; |
|||
using EasyAbp.EShop.Orders.Orders.Dtos; |
|||
using EasyAbp.EShop.Products.Products; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
[Authorize] |
|||
public class OrderAppService : CrudAppService<Order, OrderDto, Guid, GetOrderListDto, CreateOrderDto, CreateOrderDto>, |
|||
IOrderAppService |
|||
{ |
|||
protected override string CreatePolicyName { get; set; } = OrdersPermissions.Orders.Create; |
|||
protected override string GetPolicyName { get; set; } = OrdersPermissions.Orders.Default; |
|||
protected override string GetListPolicyName { get; set; } = OrdersPermissions.Orders.Default; |
|||
|
|||
private readonly INewOrderGenerator _newOrderGenerator; |
|||
private readonly IProductAppService _productAppService; |
|||
private readonly IOrderDiscountManager _orderDiscountManager; |
|||
private readonly IOrderRepository _repository; |
|||
|
|||
public OrderAppService( |
|||
INewOrderGenerator newOrderGenerator, |
|||
IProductAppService productAppService, |
|||
IOrderDiscountManager orderDiscountManager, |
|||
IOrderRepository repository) : base(repository) |
|||
{ |
|||
_newOrderGenerator = newOrderGenerator; |
|||
_productAppService = productAppService; |
|||
_orderDiscountManager = orderDiscountManager; |
|||
_repository = repository; |
|||
} |
|||
|
|||
protected override IQueryable<Order> CreateFilteredQuery(GetOrderListDto input) |
|||
{ |
|||
var query = base.CreateFilteredQuery(input); |
|||
|
|||
if (input.StoreId.HasValue) |
|||
{ |
|||
query = query.Where(x => x.StoreId == input.StoreId.Value); |
|||
} |
|||
|
|||
if (input.CustomerUserId.HasValue) |
|||
{ |
|||
query = query.Where(x => x.CustomerUserId == input.CustomerUserId.Value); |
|||
} |
|||
|
|||
return query; |
|||
} |
|||
|
|||
public override async Task<PagedResultDto<OrderDto>> GetListAsync(GetOrderListDto input) |
|||
{ |
|||
if (input.CustomerUserId != CurrentUser.GetId()) |
|||
{ |
|||
await AuthorizationService.IsGrantedAsync(OrdersPermissions.Orders.Manage); |
|||
|
|||
if (input.StoreId.HasValue) |
|||
{ |
|||
// Todo: Check if current user is an admin of the store.
|
|||
} |
|||
else |
|||
{ |
|||
await AuthorizationService.IsGrantedAsync(OrdersPermissions.Orders.CrossStore); |
|||
} |
|||
} |
|||
|
|||
return await base.GetListAsync(input); |
|||
} |
|||
|
|||
public override async Task<OrderDto> GetAsync(Guid id) |
|||
{ |
|||
await CheckGetPolicyAsync(); |
|||
|
|||
var order = await GetEntityByIdAsync(id); |
|||
|
|||
if (order.CustomerUserId != CurrentUser.GetId()) |
|||
{ |
|||
await AuthorizationService.IsGrantedAsync(OrdersPermissions.Orders.Manage); |
|||
|
|||
// Todo: Check if current user is an admin of the store.
|
|||
} |
|||
|
|||
return MapToGetOutputDto(order); |
|||
} |
|||
|
|||
public override async Task<OrderDto> CreateAsync(CreateOrderDto input) |
|||
{ |
|||
await CheckCreatePolicyAsync(); |
|||
|
|||
// Todo: Check if the store is open.
|
|||
|
|||
var productDict = await GetProductDictionaryAsync(input.OrderLines.Select(dto => dto.ProductId).ToList(), |
|||
input.StoreId); |
|||
|
|||
// Todo: Check if the product is purchasable.
|
|||
|
|||
var order = await _newOrderGenerator.GenerateAsync(input, productDict); |
|||
|
|||
await _orderDiscountManager.DiscountAsync(order, input.ExtraProperties); |
|||
|
|||
await Repository.InsertAsync(order, autoSave: true); |
|||
|
|||
return MapToGetOutputDto(order); |
|||
} |
|||
|
|||
protected virtual async Task<Dictionary<Guid, ProductDto>> GetProductDictionaryAsync( |
|||
IEnumerable<Guid> productIds, Guid storeId) |
|||
{ |
|||
var dict = new Dictionary<Guid, ProductDto>(); |
|||
|
|||
foreach (var productId in productIds) |
|||
{ |
|||
dict.Add(productId, await _productAppService.GetAsync(productId, storeId)); |
|||
} |
|||
|
|||
return dict; |
|||
} |
|||
|
|||
[RemoteService(false)] |
|||
public override Task<OrderDto> UpdateAsync(Guid id, CreateOrderDto input) |
|||
{ |
|||
throw new NotSupportedException(); |
|||
} |
|||
|
|||
[RemoteService(false)] |
|||
public override Task DeleteAsync(Guid id) |
|||
{ |
|||
throw new NotSupportedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"ManageYourProfile": "Manage your profile", |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
{ |
|||
"culture": "pl", |
|||
"texts": { |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
{ |
|||
"culture": "sl", |
|||
"texts": { |
|||
"ManageYourProfile": "Upravljajte svojim profilom", |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"ManageYourProfile": "Profil y�netimi", |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
{ |
|||
"culture": "vi", |
|||
"texts": { |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"ManageYourProfile": "管理个人资料", |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"ManageYourProfile": "管理個人資料", |
|||
"Menu:Order": "MenuOrder", |
|||
"Order": "Order", |
|||
"OrderStoreId": "OrderStoreId", |
|||
"OrderCustomerUserId": "OrderCustomerUserId", |
|||
"OrderOrderStatus": "OrderOrderStatus", |
|||
"OrderCurrency": "OrderCurrency", |
|||
"OrderProductTotalPrice": "OrderProductTotalPrice", |
|||
"OrderTotalDiscount": "OrderTotalDiscount", |
|||
"OrderTotalPrice": "OrderTotalPrice", |
|||
"OrderRefundedAmount": "OrderRefundedAmount", |
|||
"OrderCustomerRemark": "OrderCustomerRemark", |
|||
"OrderStaffRemark": "OrderStaffRemark", |
|||
"OrderPaidTime": "OrderPaidTime", |
|||
"OrderCompletionTime": "OrderCompletionTime", |
|||
"OrderCancelledTime": "OrderCancelledTime", |
|||
"OrderLine": "OrderLine", |
|||
"OrderLineProductId": "OrderLineProductId", |
|||
"OrderLineProductSkuId": "OrderLineProductSkuId", |
|||
"OrderLineQuantity": "OrderLineQuantity", |
|||
"CreateOrder": "CreateOrder", |
|||
"EditOrder": "EditOrder", |
|||
"OrderDeletionConfirmationMessage": "Are you sure to delete the order {0}?", |
|||
"SuccessfullyDeleted": "Successfully deleted" |
|||
} |
|||
} |
|||
@ -0,0 +1,39 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
[Serializable] |
|||
public class OrderEto |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public Guid StoreId { get; set; } |
|||
|
|||
public Guid CustomerUserId { get; set; } |
|||
|
|||
public OrderStatus OrderStatus { get; set; } |
|||
|
|||
public string Currency { get; set; } |
|||
|
|||
public decimal ProductTotalPrice { get; set; } |
|||
|
|||
public decimal TotalDiscount { get; set; } |
|||
|
|||
public decimal TotalPrice { get; set; } |
|||
|
|||
public decimal RefundedAmount { get; set; } |
|||
|
|||
public string CustomerRemark { get; set; } |
|||
|
|||
public string StaffRemark { get; set; } |
|||
|
|||
public DateTime? PaidTime { get; set; } |
|||
|
|||
public DateTime? CompletionTime { get; set; } |
|||
|
|||
public DateTime? CancelledTime { get; set; } |
|||
|
|||
public List<OrderLineEto> OrderLines { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using System; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
[Serializable] |
|||
public class OrderLineEto |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public Guid ProductId { get; set; } |
|||
|
|||
public Guid ProductSkuId { get; set; } |
|||
|
|||
public DateTime ProductModificationTime { get; set; } |
|||
|
|||
public DateTime ProductDetailModificationTime { get; set; } |
|||
|
|||
public string ProductName { 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 int Quantity { get; set; } |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "cs", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"ManageYourProfile": "Manage your profile" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "pl", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "pt-BR", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "sl", |
|||
"texts": { |
|||
"ManageYourProfile": "Upravljajte svojim profilom" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "tr", |
|||
"texts": { |
|||
"ManageYourProfile": "Profil yönetimi" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "vi", |
|||
"texts": { |
|||
|
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"ManageYourProfile": "管理个人资料" |
|||
} |
|||
} |
|||
@ -1,6 +0,0 @@ |
|||
{ |
|||
"culture": "zh-Hant", |
|||
"texts": { |
|||
"ManageYourProfile": "管理個人資料" |
|||
} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
using EasyAbp.EShop.Stores; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace EasyAbp.EShop.Orders |
|||
{ |
|||
[DependsOn( |
|||
typeof(EShopOrdersDomainSharedModule), |
|||
typeof(EShopStoresDomainSharedModule) |
|||
)] |
|||
public class EShopOrdersDomainModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using EasyAbp.EShop.Orders.Orders; |
|||
using EasyAbp.EShop.Stores; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.EventBus.Distributed; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace EasyAbp.EShop.Orders |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAutoMapperModule), |
|||
typeof(EShopOrdersDomainSharedModule), |
|||
typeof(EShopStoresDomainSharedModule) |
|||
)] |
|||
public class EShopOrdersDomainModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddAutoMapperObjectMapper<EShopOrdersDomainModule>(); |
|||
|
|||
Configure<AbpAutoMapperOptions>(options => |
|||
{ |
|||
options.AddProfile<OrdersDomainAutoMapperProfile>(validate: true); |
|||
}); |
|||
|
|||
Configure<AbpDistributedEventBusOptions>(options => |
|||
{ |
|||
options.EtoMappings.Add<Order, OrderEto>(typeof(EShopOrdersDomainModule)); |
|||
options.EtoMappings.Add<OrderLine, OrderLineEto>(typeof(EShopOrdersDomainModule)); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public interface IOrderDiscountManager : IDomainService |
|||
{ |
|||
Task<Order> DiscountAsync(Order order, Dictionary<string, object> inputExtraProperties); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public interface IOrderDiscountProvider |
|||
{ |
|||
Task<Order> DiscountAsync(Order order, Dictionary<string, object> inputExtraProperties); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using EasyAbp.EShop.Products.Products; |
|||
using Volo.Abp.EventBus.Distributed; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public interface IOrderProductInventoryReductionEventHandler : IDistributedEventHandler<ProductInventoryReductionAfterOrderPlacedResultEto> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public interface IOrderRepository : IRepository<Order, Guid> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,96 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using EasyAbp.EShop.Stores.Stores; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class Order : FullAuditedAggregateRoot<Guid>, IMultiTenant, IMultiStore |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
public virtual Guid StoreId { get; protected set; } |
|||
|
|||
public virtual Guid CustomerUserId { get; protected set; } |
|||
|
|||
public virtual OrderStatus OrderStatus { get; protected set; } |
|||
|
|||
[NotNull] |
|||
public virtual string Currency { get; protected set; } |
|||
|
|||
public virtual decimal ProductTotalPrice { get; protected set; } |
|||
|
|||
public virtual decimal TotalDiscount { get; protected set; } |
|||
|
|||
public virtual decimal TotalPrice { get; protected set; } |
|||
|
|||
public virtual decimal RefundedAmount { get; protected set; } |
|||
|
|||
[CanBeNull] |
|||
public virtual string CustomerRemark { get; protected set; } |
|||
|
|||
[CanBeNull] |
|||
public virtual string StaffRemark { get; protected set; } |
|||
|
|||
public virtual DateTime? PaidTime { get; protected set; } |
|||
|
|||
public virtual DateTime? CompletionTime { get; protected set; } |
|||
|
|||
public virtual DateTime? CancelledTime { get; protected set; } |
|||
|
|||
public virtual DateTime? ReducedInventoryAfterPlacingTime { get; protected set; } |
|||
|
|||
public virtual DateTime? ReducedInventoryAfterPaymentTime { get; protected set; } |
|||
|
|||
public virtual List<OrderLine> OrderLines { get; protected set; } |
|||
|
|||
protected Order() |
|||
{ |
|||
OrderLines = new List<OrderLine>(); |
|||
} |
|||
|
|||
public Order( |
|||
Guid id, |
|||
Guid? tenantId, |
|||
Guid storeId, |
|||
Guid customerUserId, |
|||
string currency, |
|||
decimal productTotalPrice, |
|||
decimal totalDiscount, |
|||
decimal totalPrice, |
|||
decimal refundedAmount, |
|||
[CanBeNull] string customerRemark |
|||
) : base(id) |
|||
{ |
|||
TenantId = tenantId; |
|||
StoreId = storeId; |
|||
CustomerUserId = customerUserId; |
|||
Currency = currency; |
|||
ProductTotalPrice = productTotalPrice; |
|||
TotalDiscount = totalDiscount; |
|||
TotalPrice = totalPrice; |
|||
RefundedAmount = refundedAmount; |
|||
CustomerRemark = customerRemark; |
|||
|
|||
OrderStatus = OrderStatus.Pending; |
|||
OrderLines = new List<OrderLine>(); |
|||
} |
|||
|
|||
public void SetOrderLines(List<OrderLine> orderLines) |
|||
{ |
|||
OrderLines = orderLines; |
|||
} |
|||
|
|||
public void SetReducedInventoryAfterPlacingTime(DateTime? time) |
|||
{ |
|||
ReducedInventoryAfterPlacingTime = time; |
|||
} |
|||
|
|||
public void SetReducedInventoryAfterPaymentTime(DateTime? time) |
|||
{ |
|||
ReducedInventoryAfterPaymentTime = time; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class OrderDiscountManager : DomainService, IOrderDiscountManager |
|||
{ |
|||
public async Task<Order> DiscountAsync(Order order, Dictionary<string, object> inputExtraProperties) |
|||
{ |
|||
foreach (var provider in ServiceProvider.GetServices<IOrderDiscountProvider>()) |
|||
{ |
|||
await provider.DiscountAsync(order, inputExtraProperties); |
|||
} |
|||
|
|||
return order; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Products.Products; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Timing; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class OrderProductInventoryReductionEventHandler : IOrderProductInventoryReductionEventHandler, ITransientDependency |
|||
{ |
|||
private readonly IClock _clock; |
|||
private readonly IOrderRepository _orderRepository; |
|||
|
|||
public OrderProductInventoryReductionEventHandler( |
|||
IClock clock, |
|||
IOrderRepository orderRepository) |
|||
{ |
|||
_clock = clock; |
|||
_orderRepository = orderRepository; |
|||
} |
|||
|
|||
[UnitOfWork(true)] |
|||
public virtual async Task HandleEventAsync(ProductInventoryReductionAfterOrderPlacedResultEto eventData) |
|||
{ |
|||
var order = await _orderRepository.GetAsync(eventData.OrderId); |
|||
|
|||
if (order.OrderStatus != OrderStatus.Pending || order.ReducedInventoryAfterPlacingTime.HasValue) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (!eventData.IsSuccess) |
|||
{ |
|||
// Todo: Cancel order.
|
|||
return; |
|||
} |
|||
|
|||
order.SetReducedInventoryAfterPaymentTime(_clock.Now); |
|||
|
|||
await _orderRepository.UpdateAsync(order, true); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using EasyAbp.EShop.Orders.Orders; |
|||
using AutoMapper; |
|||
|
|||
namespace EasyAbp.EShop.Orders |
|||
{ |
|||
public class OrdersDomainAutoMapperProfile : Profile |
|||
{ |
|||
public OrdersDomainAutoMapperProfile() |
|||
{ |
|||
/* You can configure your AutoMapper mapping configuration here. |
|||
* Alternatively, you can split your mapping configurations |
|||
* into multiple profile classes for a better organization. */ |
|||
CreateMap<Order, OrderEto>(); |
|||
CreateMap<OrderLine, OrderLineEto>(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,45 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using EasyAbp.EShop.Stores.Stores; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class Order : FullAuditedAggregateRoot<Guid>, IMultiTenant, IMultiStore |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
public virtual Guid StoreId { get; protected set; } |
|||
|
|||
public virtual Guid CustomerUserId { get; protected set; } |
|||
|
|||
public virtual OrderStatus OrderStatus { get; protected set; } |
|||
|
|||
[NotNull] |
|||
public virtual string Currency { get; protected set; } |
|||
|
|||
public virtual decimal ProductTotalPrice { get; protected set; } |
|||
|
|||
public virtual decimal TotalDiscount { get; protected set; } |
|||
|
|||
public virtual decimal TotalPrice { get; protected set; } |
|||
|
|||
public virtual decimal RefundedAmount { get; protected set; } |
|||
|
|||
[CanBeNull] |
|||
public virtual string CustomerRemark { get; protected set; } |
|||
|
|||
[CanBeNull] |
|||
public virtual string StaffRemark { get; protected set; } |
|||
|
|||
public virtual DateTime? PaidTime { get; protected set; } |
|||
|
|||
public virtual DateTime? CompletionTime { get; protected set; } |
|||
|
|||
public virtual DateTime? CancelledTime { get; protected set; } |
|||
|
|||
public virtual List<OrderLine> OrderLines { get; protected set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using EasyAbp.EShop.Orders.EntityFrameworkCore; |
|||
using Volo.Abp.Domain.Repositories.EntityFrameworkCore; |
|||
using Volo.Abp.EntityFrameworkCore; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class OrderRepository : EfCoreRepository<OrdersDbContext, Order, Guid>, IOrderRepository |
|||
{ |
|||
public OrderRepository(IDbContextProvider<OrdersDbContext> dbContextProvider) : base(dbContextProvider) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,4 +1,4 @@ |
|||
namespace EasyAbp.EShop.Orders.Web.Pages.Orders |
|||
namespace EasyAbp.EShop.Orders.Web.Pages.EShop.Orders |
|||
{ |
|||
public class IndexModel : OrdersPageModel |
|||
{ |
|||
@ -0,0 +1,54 @@ |
|||
@page |
|||
@using EasyAbp.EShop.Orders.Web.Pages.EShop.Orders.Orders.Order |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Layout |
|||
@inherits EasyAbp.EShop.Orders.Web.Pages.OrdersPage |
|||
@model IndexModel |
|||
@inject IPageLayout PageLayout |
|||
@{ |
|||
PageLayout.Content.Title = L["Order"].Value; |
|||
PageLayout.Content.BreadCrumb.Add(L["Menu:Order"].Value); |
|||
PageLayout.Content.MenuItemName = "Order"; |
|||
|
|||
var cardTitle = @L["Order"].Value; |
|||
|
|||
if (Model.StoreName != null) |
|||
{ |
|||
cardTitle += $" - {Model.StoreName}"; |
|||
} |
|||
|
|||
if (Model.CustomerUserName != null) |
|||
{ |
|||
cardTitle += $" - {Model.CustomerUserName}"; |
|||
} |
|||
} |
|||
|
|||
@section scripts |
|||
{ |
|||
<abp-script src="/Pages/EShop/Orders/Orders/Order/index.js" /> |
|||
} |
|||
@section styles |
|||
{ |
|||
<abp-style src="/Pages/EShop/Orders/Orders/Order/index.css"/> |
|||
} |
|||
|
|||
<abp-card> |
|||
<abp-card-header> |
|||
<abp-row> |
|||
<abp-column size-md="_6"> |
|||
<abp-card-title>@cardTitle</abp-card-title> |
|||
</abp-column> |
|||
</abp-row> |
|||
</abp-card-header> |
|||
<abp-card-body> |
|||
<abp-table striped-rows="true" id="OrderTable" class="nowrap"> |
|||
<thead> |
|||
<tr> |
|||
<th>@L["Actions"]</th> |
|||
<th>@L["OrderCustomerUserId"]</th> |
|||
<th>@L["OrderOrderStatus"]</th> |
|||
<th>@L["OrderTotalPrice"]</th> |
|||
</tr> |
|||
</thead> |
|||
</abp-table> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
@ -0,0 +1,40 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Stores.Stores; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Web.Pages.EShop.Orders.Orders.Order |
|||
{ |
|||
public class IndexModel : OrdersPageModel |
|||
{ |
|||
private readonly IStoreAppService _storeAppService; |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public Guid? StoreId { get; set; } |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public Guid? CustomerUserId { get; set; } |
|||
|
|||
public string StoreName { get; set; } |
|||
|
|||
public string CustomerUserName { get; set; } |
|||
|
|||
public IndexModel(IStoreAppService storeAppService) |
|||
{ |
|||
_storeAppService = storeAppService; |
|||
} |
|||
|
|||
public virtual async Task OnGetAsync() |
|||
{ |
|||
if (StoreId.HasValue) |
|||
{ |
|||
StoreName = (await _storeAppService.GetAsync(StoreId.Value)).Name; |
|||
} |
|||
|
|||
if (CustomerUserId.HasValue) |
|||
{ |
|||
// Todo: get username
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,48 @@ |
|||
$(function () { |
|||
|
|||
var l = abp.localization.getResource('Orders'); |
|||
|
|||
var service = easyAbp.eShop.orders.orders.order; |
|||
|
|||
var dataTable = $('#OrderTable').DataTable(abp.libs.datatables.normalizeConfiguration({ |
|||
processing: true, |
|||
serverSide: true, |
|||
paging: true, |
|||
searching: false, |
|||
autoWidth: false, |
|||
scrollCollapse: true, |
|||
order: [[1, "asc"]], |
|||
ajax: abp.libs.datatables.createAjax(service.getList), |
|||
columnDefs: [ |
|||
{ |
|||
rowAction: { |
|||
items: |
|||
[ |
|||
{ |
|||
text: l('Detail'), |
|||
action: function (data) { |
|||
editModal.open({ id: data.record.id }); |
|||
} |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
{ data: "customerUserId" }, |
|||
{ data: "orderStatus" }, |
|||
{ data: "totalPrice" }, |
|||
] |
|||
})); |
|||
|
|||
createModal.onResult(function () { |
|||
dataTable.ajax.reload(); |
|||
}); |
|||
|
|||
editModal.onResult(function () { |
|||
dataTable.ajax.reload(); |
|||
}); |
|||
|
|||
$('#NewOrderButton').click(function (e) { |
|||
e.preventDefault(); |
|||
createModal.open(); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,26 @@ |
|||
using Shouldly; |
|||
using System.Threading.Tasks; |
|||
using Xunit; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class OrderAppServiceTests : OrdersApplicationTestBase |
|||
{ |
|||
private readonly IOrderAppService _orderAppService; |
|||
|
|||
public OrderAppServiceTests() |
|||
{ |
|||
_orderAppService = GetRequiredService<IOrderAppService>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Test1() |
|||
{ |
|||
// Arrange
|
|||
|
|||
// Act
|
|||
|
|||
// Assert
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Xunit; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class OrderDomainTests : OrdersDomainTestBase |
|||
{ |
|||
public OrderDomainTests() |
|||
{ |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Test1() |
|||
{ |
|||
// Arrange
|
|||
|
|||
// Assert
|
|||
|
|||
// Assert
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Orders.Orders; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Xunit; |
|||
|
|||
namespace EasyAbp.EShop.Orders.EntityFrameworkCore.Orders |
|||
{ |
|||
public class OrderRepositoryTests : OrdersEntityFrameworkCoreTestBase |
|||
{ |
|||
private readonly IRepository<Order, Guid> _orderRepository; |
|||
|
|||
public OrderRepositoryTests() |
|||
{ |
|||
_orderRepository = GetRequiredService<IRepository<Order, Guid>>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Test1() |
|||
{ |
|||
await WithUnitOfWorkAsync(async () => |
|||
{ |
|||
// Arrange
|
|||
|
|||
// Act
|
|||
|
|||
//Assert
|
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System; |
|||
|
|||
namespace EasyAbp.EShop.Products.Products |
|||
{ |
|||
[Serializable] |
|||
public class ProductInventoryReductionAfterOrderPlacedResultEto |
|||
{ |
|||
public Guid OrderId { get; set; } |
|||
|
|||
public bool IsSuccess { get; set; } |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue