Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions samples/VirtoCommerce.OrdersModule2.Web/Module.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
using Microsoft.Extensions.DependencyInjection;
using VirtoCommerce.CoreModule.Core.Common;
using VirtoCommerce.OrdersModule.Core.Model;
using VirtoCommerce.OrdersModule.Core.Services;
using VirtoCommerce.OrdersModule.Data.Model;
using VirtoCommerce.OrdersModule.Data.Repositories;
using VirtoCommerce.OrdersModule2.Web.Authorization;
using VirtoCommerce.OrdersModule2.Web.Extensions;
using VirtoCommerce.OrdersModule2.Web.Model;
using VirtoCommerce.OrdersModule2.Web.Repositories;
using VirtoCommerce.OrdersModule2.Web.Services;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.Modularity;
using VirtoCommerce.Platform.Core.Security;
Expand All @@ -37,6 +39,7 @@ public void Initialize(IServiceCollection serviceCollection)

serviceCollection.AddTransient<IOrderRepository, OrderRepository2>();
serviceCollection.AddTransient<IAuthorizationHandler, CustomOrderAuthorizationHandler>();
serviceCollection.AddScoped<ICustomerOrderDataProtectionService, SampleCustomerOrderDataProtectionService>();

serviceCollection.AddValidators();
}
Expand All @@ -48,8 +51,9 @@ public void PostInitialize(IApplicationBuilder appBuilder)

AbstractTypeFactory<PermissionScope>.RegisterType<OrderSelectedStatusScope>();

var permissionsProvider = appBuilder.ApplicationServices.GetRequiredService<IPermissionsRegistrar>();
permissionsProvider.WithAvailabeScopesForPermissions(
var permissionsRegistrar = appBuilder.ApplicationServices.GetRequiredService<IPermissionsRegistrar>();
permissionsRegistrar.RegisterPermissions(ModuleInfo.Id, ModuleInfo.Title, ModuleConstants.Permissions.AllPermissions);
permissionsRegistrar.WithAvailabeScopesForPermissions(
[
// Permission list
OrdersModule.Core.ModuleConstants.Security.Permissions.Read
Expand Down
12 changes: 12 additions & 0 deletions samples/VirtoCommerce.OrdersModule2.Web/ModuleConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ namespace VirtoCommerce.OrdersModule2.Web
{
public class ModuleConstants
{
public static class Permissions
{
public const string ReadPricesDirect = "order_samples:read_prices_direct";
public const string ReadPricesIndirect = "order_samples:read_prices_indirect";

public static string[] AllPermissions { get; } =
[
ReadPricesDirect,
ReadPricesIndirect,
];
}

public static class Settings
{
public static class General
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using VirtoCommerce.OrdersModule.Core.Model;
using VirtoCommerce.OrdersModule.Core.Search.Indexed;
using VirtoCommerce.OrdersModule.Core.Services;
using VirtoCommerce.OrdersModule.Data.Services;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.Security;
using VirtoCommerce.StoreModule.Core.Model;
using VirtoCommerce.StoreModule.Core.Services;

namespace VirtoCommerce.OrdersModule2.Web.Services;

public sealed class SampleCustomerOrderDataProtectionService(
ICustomerOrderService crudService,
ICustomerOrderSearchService searchService,
IIndexedCustomerOrderSearchService indexedSearchService,
IUserNameResolver userNameResolver,
SignInManager<ApplicationUser> signInManager,
IStoreService storeService,
IOptions<MvcNewtonsoftJsonOptions> jsonOptions)
: CustomerOrderDataProtectionService(crudService, searchService, indexedSearchService, userNameResolver, signInManager)
{
private readonly MvcNewtonsoftJsonOptions _jsonOptions = jsonOptions.Value;

protected override async Task<bool> CanReadPrices(ClaimsPrincipal user, CustomerOrder order)
{
var canReadPrices = await base.CanReadPrices(user, order);

if (!canReadPrices)
{
var store = await storeService.GetByIdAsync(order.StoreId);
canReadPrices = store != null && CanReadPricesForStore(user, store);
}

return canReadPrices;
}

private bool CanReadPricesForStore(ClaimsPrincipal user, Store store)
{
var isDirectDistributor = store.Name.ContainsIgnoreCase("Direct");

var permissionName = isDirectDistributor
? ModuleConstants.Permissions.ReadPricesDirect
: ModuleConstants.Permissions.ReadPricesIndirect;

var permission = user.FindPermission(permissionName, _jsonOptions.SerializerSettings);

return permission != null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Collections;
using System.Linq;
using System.Reflection;
using VirtoCommerce.CoreModule.Core.Common;

namespace VirtoCommerce.OrdersModule.Core.Extensions;

public static class OperationExtensions
{
public static void FillChildOperations(this IOperation operation)
{
var properties = operation.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

var childOperations = properties
.Where(x => x.PropertyType.GetInterface(nameof(IOperation)) != null)
.Select(x => (IOperation)x.GetValue(operation)).Where(x => x != null)
.ToList();

// Handle collections
var collections = properties
.Where(x => x.Name != nameof(operation.ChildrenOperations) && x.GetIndexParameters().Length == 0)
.Select(x => x.GetValue(operation, index: null))
.Where(x => x is IEnumerable and not string)
.Cast<IEnumerable>();

foreach (var collection in collections)
{
childOperations.AddRange(collection.OfType<IOperation>());
}

operation.ChildrenOperations = childOperations;
}
}
93 changes: 67 additions & 26 deletions src/VirtoCommerce.OrdersModule.Core/Model/CustomerOrder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using VirtoCommerce.CoreModule.Core.Common;
using VirtoCommerce.CoreModule.Core.Tax;
using VirtoCommerce.OrdersModule.Core.Extensions;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.Security;
using VirtoCommerce.SearchModule.Core.Model;
Expand Down Expand Up @@ -258,91 +259,129 @@ public class CustomerOrder : OrderOperation, IHasTaxDetalization, ISupportSecuri

#endregion

public virtual void ReduceDetails(string responseGroup)
public override void ReduceDetails(string responseGroup)
{
//Reduce details according to response group
base.ReduceDetails(responseGroup);

// Reduce details according to the response group
var orderResponseGroup = EnumUtility.SafeParseFlags(responseGroup, CustomerOrderResponseGroup.Full);

if (!orderResponseGroup.HasFlag(CustomerOrderResponseGroup.WithItems))
{
Items = null;
}

if (!orderResponseGroup.HasFlag(CustomerOrderResponseGroup.WithShipments))
{
Shipments = null;
}

if (!orderResponseGroup.HasFlag(CustomerOrderResponseGroup.WithInPayments))
{
InPayments = null;
}

if (!orderResponseGroup.HasFlag(CustomerOrderResponseGroup.WithAddresses))
{
Addresses = null;
}

if (!orderResponseGroup.HasFlag(CustomerOrderResponseGroup.WithDiscounts))
{
Discounts = null;
}

if (!orderResponseGroup.HasFlag(CustomerOrderResponseGroup.WithPrices))
{
TaxPercentRate = 0m;
ShippingTotalWithTax = 0m;
PaymentTotalWithTax = 0m;
DiscountAmount = 0m;
Total = 0m;
SubTotal = 0m;
SubTotalWithTax = 0m;
ShippingTotal = 0m;
PaymentTotal = 0m;
DiscountTotal = 0m;
DiscountTotalWithTax = 0m;
TaxTotal = 0m;
Sum = 0m;
Fee = 0m;
FeeTotalWithTax = 0m;
FeeTotal = 0m;
FeeTotalWithTax = 0m;
FeeWithTax = 0m;
HandlingTotal = 0m;
HandlingTotalWithTax = 0m;
PaymentDiscountTotal = 0m;
PaymentDiscountTotalWithTax = 0m;
PaymentSubTotal = 0m;
PaymentSubTotalWithTax = 0m;
PaymentTaxTotal = 0m;
PaymentTotal = 0m;
PaymentTotalWithTax = 0m;
ShippingDiscountTotal = 0m;
ShippingDiscountTotalWithTax = 0m;
ShippingSubTotal = 0m;
ShippingSubTotalWithTax = 0m;
ShippingTaxTotal = 0m;
ShippingTotal = 0m;
ShippingTotalWithTax = 0m;
SubTotal = 0m;
SubTotalDiscount = 0m;
SubTotalDiscountWithTax = 0m;
SubTotalTaxTotal = 0m;
SubTotalWithTax = 0m;
TaxPercentRate = 0m;
TaxTotal = 0m;
Total = 0m;
}

foreach (var shipment in Shipments ?? Array.Empty<Shipment>())
{
shipment.ReduceDetails(responseGroup);
}

foreach (var inPayment in InPayments ?? Array.Empty<PaymentIn>())
{
inPayment.ReduceDetails(responseGroup);
}

foreach (var item in Items ?? Array.Empty<LineItem>())
{
item.ReduceDetails(responseGroup);
}

}

public virtual void RestoreDetails(CustomerOrder order)
public override void RestoreDetails(OrderOperation operation)
{
TaxPercentRate = order.TaxPercentRate;
ShippingTotalWithTax = order.ShippingTotalWithTax;
PaymentTotalWithTax = order.PaymentTotalWithTax;
base.RestoreDetails(operation);

if (operation is not CustomerOrder order)
{
return;
}

DiscountAmount = order.DiscountAmount;
Total = order.Total;
SubTotal = order.SubTotal;
SubTotalWithTax = order.SubTotalWithTax;
ShippingTotal = order.ShippingTotal;
PaymentTotal = order.PaymentTotal;
DiscountTotal = order.DiscountTotal;
DiscountTotalWithTax = order.DiscountTotalWithTax;
TaxTotal = order.TaxTotal;
Sum = order.Sum;
Fee = order.Fee;
FeeTotalWithTax = order.FeeTotalWithTax;
FeeTotal = order.FeeTotal;
FeeTotalWithTax = order.FeeTotalWithTax;
FeeWithTax = order.FeeWithTax;
HandlingTotal = order.HandlingTotal;
HandlingTotalWithTax = order.HandlingTotalWithTax;
PaymentDiscountTotal = order.PaymentDiscountTotal;
PaymentDiscountTotalWithTax = order.PaymentDiscountTotalWithTax;
PaymentSubTotal = order.PaymentSubTotal;
PaymentSubTotalWithTax = order.PaymentSubTotalWithTax;
PaymentTaxTotal = order.PaymentTaxTotal;
PaymentTotal = order.PaymentTotal;
PaymentTotalWithTax = order.PaymentTotalWithTax;
ShippingDiscountTotal = order.ShippingDiscountTotal;
ShippingDiscountTotalWithTax = order.ShippingDiscountTotalWithTax;
ShippingSubTotal = order.ShippingSubTotal;
ShippingSubTotalWithTax = order.ShippingSubTotalWithTax;
ShippingTaxTotal = order.ShippingTaxTotal;
ShippingTotal = order.ShippingTotal;
ShippingTotalWithTax = order.ShippingTotalWithTax;
SubTotal = order.SubTotal;
SubTotalDiscount = order.SubTotalDiscount;
SubTotalDiscountWithTax = order.SubTotalDiscountWithTax;
SubTotalTaxTotal = order.SubTotalTaxTotal;
SubTotalWithTax = order.SubTotalWithTax;
TaxPercentRate = order.TaxPercentRate;
TaxTotal = order.TaxTotal;
Total = order.Total;

foreach (var shipment in order.Shipments ?? Array.Empty<Shipment>())
{
Expand Down Expand Up @@ -377,6 +416,8 @@ public override object Clone()
result.Discounts = Discounts?.Select(x => x.Clone()).OfType<Discount>().ToList();
result.FeeDetails = FeeDetails?.Select(x => x.Clone()).OfType<FeeDetail>().ToList();

result.FillChildOperations();

return result;
}

Expand Down
33 changes: 27 additions & 6 deletions src/VirtoCommerce.OrdersModule.Core/Model/LineItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ public class LineItem : AuditableEntity, IHasOuterId, IHasTaxDetalization, ISupp

public virtual void ReduceDetails(string responseGroup)
{
// Reduce details according to the response group
var orderResponseGroup = EnumUtility.SafeParseFlags(responseGroup, CustomerOrderResponseGroup.Full);

if (!orderResponseGroup.HasFlag(CustomerOrderResponseGroup.WithDiscounts))
Expand All @@ -164,23 +165,43 @@ public virtual void ReduceDetails(string responseGroup)

if (!orderResponseGroup.HasFlag(CustomerOrderResponseGroup.WithPrices))
{
Price = 0m;
PriceWithTax = 0m;
DiscountAmount = 0m;
DiscountAmountWithTax = 0m;
TaxTotal = 0m;
DiscountTotal = 0m;
DiscountTotalWithTax = 0m;
ExtendedPrice = 0m;
ExtendedPriceWithTax = 0m;
Fee = 0m;
FeeWithTax = 0m;
ListTotal = 0m;
ListTotalWithTax = 0m;
PlacedPrice = 0m;
PlacedPriceWithTax = 0m;
Price = 0m;
PriceWithTax = 0m;
TaxPercentRate = 0m;
TaxTotal = 0m;
}
}

public virtual void RestoreDetails(LineItem item)
{
Price = item.Price;
PriceWithTax = item.PriceWithTax;
DiscountAmount = item.DiscountAmount;
DiscountAmountWithTax = item.DiscountAmountWithTax;
TaxTotal = item.TaxTotal;
DiscountTotal = item.DiscountTotal;
DiscountTotalWithTax = item.DiscountTotalWithTax;
ExtendedPrice = item.ExtendedPrice;
ExtendedPriceWithTax = item.ExtendedPriceWithTax;
Fee = item.Fee;
FeeWithTax = item.FeeWithTax;
ListTotal = item.ListTotal;
ListTotalWithTax = item.ListTotalWithTax;
PlacedPrice = item.PlacedPrice;
PlacedPriceWithTax = item.PlacedPriceWithTax;
Price = item.Price;
PriceWithTax = item.PriceWithTax;
TaxPercentRate = item.TaxPercentRate;
TaxTotal = item.TaxTotal;
}

#region ICloneable members
Expand Down
Loading