Skip to content

Commit 0f784e8

Browse files
committed
Add configuration to skip AllOrNoneAsync.
1 parent b2b28cb commit 0f784e8

8 files changed

Lines changed: 133 additions & 8 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#nullable enable
2+
3+
using Microsoft.AspNetCore.Authorization;
4+
using Microsoft.AspNetCore.Http;
5+
using OrchardCore.Commerce.Tax.Models;
6+
using OrchardCore.Commerce.Tax.Permissions;
7+
using OrchardCore.DisplayManagement.Entities;
8+
using OrchardCore.DisplayManagement.Handlers;
9+
using OrchardCore.DisplayManagement.Views;
10+
using OrchardCore.Environment.Shell;
11+
using OrchardCore.Settings;
12+
using System.Threading.Tasks;
13+
namespace OrchardCore.Commerce.Tax.Drivers;
14+
15+
public class TaxSettingsDisplayDriver : SiteDisplayDriver<TaxSettings>
16+
{
17+
public const string GroupId = nameof(TaxSettings);
18+
19+
private readonly IShellHost _shellHost;
20+
private readonly ShellSettings _shellSettings;
21+
private readonly IHttpContextAccessor _hca;
22+
private readonly IAuthorizationService _authorizationService;
23+
24+
public TaxSettingsDisplayDriver(
25+
IShellHost shellHost,
26+
ShellSettings shellSettings,
27+
IHttpContextAccessor hca,
28+
IAuthorizationService authorizationService)
29+
{
30+
_shellHost = shellHost;
31+
_shellSettings = shellSettings;
32+
_hca = hca;
33+
_authorizationService = authorizationService;
34+
}
35+
36+
protected override string SettingsGroupId => GroupId;
37+
38+
public override async Task<IDisplayResult?> EditAsync(ISite model, TaxSettings section, BuildEditorContext context)
39+
{
40+
if (!await AuthorizeAsync())
41+
{
42+
return null;
43+
}
44+
45+
context.AddTenantReloadWarningWrapper();
46+
47+
return Initialize<TaxSettings>(
48+
$"{nameof(TaxSettings)}_Edit",
49+
model => model.IgnoreAllOrNone = section.IgnoreAllOrNone)
50+
.PlaceInContent()
51+
.OnGroup(SettingsGroupId);
52+
}
53+
54+
public override async Task<IDisplayResult?> UpdateAsync(ISite model, TaxSettings section, UpdateEditorContext context)
55+
{
56+
if (!await AuthorizeAsync())
57+
{
58+
return null;
59+
}
60+
61+
if (await context.CreateModelMaybeAsync<TaxSettings>(Prefix, AuthorizeAsync) is { } viewModel)
62+
{
63+
section.IgnoreAllOrNone = viewModel.IgnoreAllOrNone;
64+
}
65+
66+
return await EditAsync(model, section, context);
67+
}
68+
69+
private Task<bool> AuthorizeAsync() =>
70+
_authorizationService.AuthorizeAsync(_hca.HttpContext?.User, TaxRatePermissions.ManageTaxSettings);
71+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace OrchardCore.Commerce.Tax.Models;
2+
3+
public class TaxSettings
4+
{
5+
public bool IgnoreAllOrNone { get; set; }
6+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Lombiq.HelpfulLibraries.OrchardCore.Navigation;
2+
using Microsoft.AspNetCore.Http;
3+
using Microsoft.Extensions.Localization;
4+
using OrchardCore.Commerce.Tax.Drivers;
5+
using OrchardCore.Commerce.Tax.Permissions;
6+
using OrchardCore.Navigation;
7+
8+
namespace OrchardCore.Commerce.Tax.Navigation;
9+
10+
public class TaxSettingsAdminMenu : AdminMenuNavigationProviderBase
11+
{
12+
public TaxSettingsAdminMenu(IHttpContextAccessor hca, IStringLocalizer<TaxSettingsAdminMenu> stringLocalizer)
13+
: base(hca, stringLocalizer)
14+
{
15+
}
16+
17+
protected override void Build(NavigationBuilder builder) =>
18+
builder
19+
.Add(T["Configuration"], configuration => configuration
20+
.Add(T["Commerce"], commerce => commerce
21+
.Add(T["Tax"], T["Tax"], entry => entry
22+
.Action("Index", "Admin", new
23+
{
24+
area = "OrchardCore.Settings",
25+
groupId = TaxSettingsDisplayDriver.GroupId,
26+
})
27+
.Permission(TaxRatePermissions.ManageTaxSettings)
28+
.LocalNav())));
29+
}

src/Modules/OrchardCore.Commerce.Tax/Permissions/TaxRatePermissions.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ public class TaxRatePermissions : AdminPermissionBase
88
{
99
public static readonly Permission ManageCustomTaxRates =
1010
new(nameof(ManageCustomTaxRates), "Manage Custom Tax Rates");
11+
public static readonly Permission ManageTaxSettings =
12+
new(nameof(ManageTaxSettings), "Manage Tax Settings");
1113

12-
protected override IEnumerable<Permission> AdminPermissions { get; } = [ManageCustomTaxRates];
14+
protected override IEnumerable<Permission> AdminPermissions { get; } = [ManageCustomTaxRates, ManageTaxSettings];
1315
}

src/Modules/OrchardCore.Commerce.Tax/Startup.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ public class Startup : StartupBase
2020
{
2121
public override void ConfigureServices(IServiceCollection services)
2222
{
23+
services.AddScoped<IPermissionProvider, TaxRatePermissions>();
2324
services.AddTransient<IConfigureOptions<ResourceManagementOptions>, ResourceManagementOptionsConfiguration>();
2425
services.AddContentPart<TaxPart>()
2526
.WithMigration<TaxPartMigrations>();
27+
services.AddSiteDisplayDriver<TaxSettingsDisplayDriver>();
28+
services.AddScoped<INavigationProvider, TaxSettingsAdminMenu>();
2629
}
2730
}
2831

@@ -31,7 +34,6 @@ public class CustomTaxRatesStartup : StartupBase
3134
{
3235
public override void ConfigureServices(IServiceCollection services)
3336
{
34-
services.AddScoped<IPermissionProvider, TaxRatePermissions>();
3537
services.AddScoped<ITaxRateSettingsHeaderProvider, TaxRateSettingsDisplayDriver>();
3638
services.AddSiteDisplayDriver<TaxRateSettingsDisplayDriver>();
3739
services.AddTransient<IConfigureOptions<TaxRateSettings>, TaxRateSettingsConfiguration>();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@model OrchardCore.Commerce.Tax.Models.TaxSettings
2+
3+
<div class="mb-3" asp-validation-class-for="IgnoreAllOrNone">
4+
<div class="w-sm-75 w-md-50 w-lg-25 pe-md-3">
5+
<input asp-for="IgnoreAllOrNone" type="checkbox" class="form-check-input content-preview-select" checked="@Model.IgnoreAllOrNone" />
6+
<label asp-for="IgnoreAllOrNone" class="form-check-label">@T["Skip consistent applicability check"]</label>
7+
</div>
8+
<span class="hint">@T["If checked, the shop won't verify that every product in the cart has a valid Tax part. If you check this, you are responsible for verifying that all taxable product types have attached and correctly configured tax parts."]</span>
9+
</div>

src/Modules/OrchardCore.Commerce/Services/LocalTaxProvider.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using OrchardCore.Commerce.MoneyDataType.Extensions;
55
using OrchardCore.Commerce.Tax.Models;
66
using OrchardCore.ContentManagement;
7+
using OrchardCore.Settings;
78
using System.Collections.Generic;
89
using System.Linq;
910
using System.Threading.Tasks;
@@ -12,9 +13,13 @@ namespace OrchardCore.Commerce.Services;
1213

1314
public class LocalTaxProvider : ITaxProvider
1415
{
16+
private readonly ISiteService _siteService;
17+
1518
// This is the simplest, lowest priority option and if anything else is applicable it should supersede this.
1619
public int Order => int.MaxValue;
1720

21+
public LocalTaxProvider(ISiteService siteService) => _siteService = siteService;
22+
1823
public Task<PromotionAndTaxProviderContext> UpdateAsync(PromotionAndTaxProviderContext model)
1924
{
2025
var items = model.Items.AsList();
@@ -37,8 +42,9 @@ public Task<PromotionAndTaxProviderContext> UpdateAsync(PromotionAndTaxProviderC
3742
});
3843
}
3944

40-
public Task<bool> IsApplicableAsync(PromotionAndTaxProviderContext model) =>
41-
ITaxProvider.AllOrNoneAsync(model, items => Task.FromResult(HasTaxRate(items)));
45+
public async Task<bool> IsApplicableAsync(PromotionAndTaxProviderContext model) =>
46+
(await _siteService.GetSettingsAsync<TaxSettings>())?.IgnoreAllOrNone == true ||
47+
await ITaxProvider.AllOrNoneAsync(model, items => Task.FromResult(HasTaxRate(items)));
4248

4349
private int HasTaxRate(IList<PromotionAndTaxProviderContextLineItem> items) => items
4450
.SelectWhere(item => item.Content.ContentItem.As<TaxPart>())

src/Modules/OrchardCore.Commerce/Services/TaxRateTaxProvider.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ public class TaxRateTaxProvider : ITaxProvider
2222

2323
public async Task<PromotionAndTaxProviderContext> UpdateAsync(PromotionAndTaxProviderContext model)
2424
{
25-
var siteSettings = await _siteService.GetSiteSettingsAsync();
26-
var taxRates = siteSettings.As<TaxRateSettings>();
25+
var taxRates = await _siteService.GetSettingsAsync<TaxRateSettings>();
2726

2827
var items = model.Items.AsList();
2928

@@ -47,8 +46,9 @@ public async Task<PromotionAndTaxProviderContext> UpdateAsync(PromotionAndTaxPro
4746
return model with { Items = updatedItems };
4847
}
4948

50-
public Task<bool> IsApplicableAsync(PromotionAndTaxProviderContext model) =>
51-
ITaxProvider.AllOrNoneAsync(model, async items =>
49+
public async Task<bool> IsApplicableAsync(PromotionAndTaxProviderContext model) =>
50+
(await _siteService.GetSettingsAsync<TaxSettings>())?.IgnoreAllOrNone == true ||
51+
await ITaxProvider.AllOrNoneAsync(model, async items =>
5252
{
5353
var siteSettings = await _siteService.GetSiteSettingsAsync();
5454
var taxRates = siteSettings.As<TaxRateSettings>();

0 commit comments

Comments
 (0)