mirror of https://github.com/EasyAbp/EShop.git
Browse Source
Close #79 Remove CreatePaymentEto in PaymentCreationResource Fix BasicPaymentCreationAuthorizationHandlerpull/103/head
19 changed files with 181 additions and 168 deletions
@ -0,0 +1,53 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Orders.Orders.Dtos; |
|||
using EasyAbp.EShop.Products.Products; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class BasicOrderCreationAuthorizationHandler : OrderCreationAuthorizationHandler |
|||
{ |
|||
protected override async Task HandleOrderCreationAsync(AuthorizationHandlerContext context, |
|||
OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource) |
|||
{ |
|||
if (!await IsProductsPublishedAsync(resource.Input, resource.ProductDictionary)) |
|||
{ |
|||
context.Fail(); |
|||
return; |
|||
} |
|||
|
|||
if (!await IsInventoriesSufficientAsync(resource.Input, resource.ProductDictionary)) |
|||
{ |
|||
context.Fail(); |
|||
return; |
|||
} |
|||
|
|||
context.Succeed(requirement); |
|||
} |
|||
|
|||
protected virtual Task<bool> IsProductsPublishedAsync(CreateOrderDto input, |
|||
Dictionary<Guid, ProductDto> productDictionary) |
|||
{ |
|||
return Task.FromResult( |
|||
input.OrderLines.Select(dto => dto.ProductId).Distinct().ToArray() |
|||
.All(productId => productDictionary[productId].IsPublished) |
|||
); |
|||
} |
|||
|
|||
protected virtual Task<bool> IsInventoriesSufficientAsync(CreateOrderDto input, |
|||
Dictionary<Guid, ProductDto> productDictionary) |
|||
{ |
|||
return Task.FromResult( |
|||
!(from orderLine in input.OrderLines |
|||
let product = productDictionary[orderLine.ProductId] |
|||
let inventory = product.ProductSkus.Single(sku => sku.Id == orderLine.ProductSkuId).Inventory |
|||
where product.InventoryStrategy != InventoryStrategy.NoNeed && inventory < orderLine.Quantity |
|||
select orderLine).Any() |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -1,55 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Orders.Orders.Dtos; |
|||
using EasyAbp.EShop.Products.Products; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class BasicPurchasableCheckProvider : IPurchasableCheckProvider, ITransientDependency |
|||
{ |
|||
public virtual async Task CheckAsync(CreateOrderDto input, Dictionary<Guid, ProductDto> productDict, |
|||
Dictionary<string, object> orderExtraProperties) |
|||
{ |
|||
await CheckProductsPublishedAsync(input, productDict); |
|||
|
|||
await CheckInventoriesSufficientAsync(input, productDict); |
|||
} |
|||
|
|||
protected virtual Task CheckProductsPublishedAsync(CreateOrderDto input, |
|||
Dictionary<Guid, ProductDto> productDict) |
|||
{ |
|||
foreach (var productId in input.OrderLines.Select(dto => dto.ProductId).Distinct().ToArray()) |
|||
{ |
|||
if (!productDict[productId].IsPublished) |
|||
{ |
|||
throw new NotPurchasableException(productId, null, "Unpublished project"); |
|||
} |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
protected virtual Task CheckInventoriesSufficientAsync(CreateOrderDto input, |
|||
Dictionary<Guid, ProductDto> productDict) |
|||
{ |
|||
foreach (var orderLine in input.OrderLines) |
|||
{ |
|||
var product = productDict[orderLine.ProductId]; |
|||
var inventory = product.ProductSkus |
|||
.Single(sku => sku.Id == orderLine.ProductSkuId).Inventory; |
|||
|
|||
if (product.InventoryStrategy != InventoryStrategy.NoNeed && inventory < orderLine.Quantity) |
|||
{ |
|||
throw new NotPurchasableException(orderLine.ProductId, orderLine.ProductSkuId, |
|||
"Insufficient inventory"); |
|||
} |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using Volo.Abp; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class CurrencyIsLimitException : BusinessException |
|||
{ |
|||
public CurrencyIsLimitException(string expectedCurrency) : base( |
|||
"CurrencyIsLimit", |
|||
$"Only the specified currency {expectedCurrency} is allowed.") |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
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 IPurchasableCheckProvider |
|||
{ |
|||
Task CheckAsync(CreateOrderDto input, Dictionary<Guid, ProductDto> productDict, |
|||
Dictionary<string, object> orderExtraProperties); |
|||
} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
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 IPurchasableChecker |
|||
{ |
|||
Task CheckAsync(CreateOrderDto input, Dictionary<Guid, ProductDto> productDict, |
|||
Dictionary<string, object> orderExtraProperties); |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
using System; |
|||
using Volo.Abp; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class NotPurchasableException : BusinessException |
|||
{ |
|||
public NotPurchasableException(Guid productId, Guid? productSkuId, string reason) : base( |
|||
message: $"Product {productId} (SKU: {productSkuId}) cannot be purchased, the reason is: {reason}") |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public abstract class OrderCreationAuthorizationHandler : AuthorizationHandler<OrderOperationAuthorizationRequirement, OrderCreationResource> |
|||
{ |
|||
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, OrderOperationAuthorizationRequirement requirement, |
|||
OrderCreationResource resource) |
|||
{ |
|||
if (requirement.OrderOperation != OrderOperation.Creation) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
await HandleOrderCreationAsync(context, requirement, resource); |
|||
} |
|||
|
|||
protected abstract Task HandleOrderCreationAsync(AuthorizationHandlerContext context, |
|||
OrderOperationAuthorizationRequirement requirement, OrderCreationResource resource); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using EasyAbp.EShop.Orders.Orders.Dtos; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class OrderCreationResource |
|||
{ |
|||
public CreateOrderDto Input { get; set; } |
|||
|
|||
public Dictionary<Guid, ProductDto> ProductDictionary { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using System; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
[Flags] |
|||
public enum OrderOperation |
|||
{ |
|||
Creation = 0 |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class OrderOperationAuthorizationRequirement : IAuthorizationRequirement |
|||
{ |
|||
public OrderOperation OrderOperation { get; } |
|||
|
|||
public OrderOperationAuthorizationRequirement(OrderOperation orderOperation) |
|||
{ |
|||
OrderOperation = orderOperation; |
|||
} |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using EasyAbp.EShop.Orders.Orders.Dtos; |
|||
using EasyAbp.EShop.Products.Products.Dtos; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace EasyAbp.EShop.Orders.Orders |
|||
{ |
|||
public class PurchasableChecker : IPurchasableChecker, ITransientDependency |
|||
{ |
|||
private readonly IServiceProvider _serviceProvider; |
|||
|
|||
public PurchasableChecker(IServiceProvider serviceProvider) |
|||
{ |
|||
_serviceProvider = serviceProvider; |
|||
} |
|||
|
|||
public virtual async Task CheckAsync(CreateOrderDto input, Dictionary<Guid, ProductDto> productDict, |
|||
Dictionary<string, object> orderExtraProperties) |
|||
{ |
|||
var providers = _serviceProvider.GetServices<IPurchasableCheckProvider>(); |
|||
|
|||
foreach (var provider in providers) |
|||
{ |
|||
await provider.CheckAsync(input, productDict, orderExtraProperties); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue