1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-21 11:34:31 -05:00

[PM-19431] Organization plan change upgrade path not applying correct automatic tax flag

This commit is contained in:
Jonas Hendrickx 2025-03-24 10:52:22 +00:00
parent 3259803936
commit e00c8cc457
6 changed files with 37 additions and 9 deletions

View File

@ -2,6 +2,9 @@
namespace Bit.Core.Billing.Services; namespace Bit.Core.Billing.Services;
/// <summary>
/// Responsible for defining the correct automatic tax strategy for either personal use of business use.
/// </summary>
public interface IAutomaticTaxFactory public interface IAutomaticTaxFactory
{ {
Task<IAutomaticTaxStrategy> CreateAsync(AutomaticTaxFactoryParameters parameters); Task<IAutomaticTaxStrategy> CreateAsync(AutomaticTaxFactoryParameters parameters);

View File

@ -3,10 +3,13 @@ using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Pricing; using Bit.Core.Billing.Pricing;
using Bit.Core.Billing.Services.Contracts; using Bit.Core.Billing.Services.Contracts;
using Bit.Core.Entities; using Bit.Core.Entities;
using Bit.Core.Services;
namespace Bit.Core.Billing.Services.Implementations.AutomaticTax; namespace Bit.Core.Billing.Services.Implementations.AutomaticTax;
public class AutomaticTaxFactory(IPricingClient pricingClient) : IAutomaticTaxFactory public class AutomaticTaxFactory(
IFeatureService featureService,
IPricingClient pricingClient) : IAutomaticTaxFactory
{ {
public const string BusinessUse = "business-use"; public const string BusinessUse = "business-use";
public const string PersonalUse = "personal-use"; public const string PersonalUse = "personal-use";
@ -24,15 +27,15 @@ public class AutomaticTaxFactory(IPricingClient pricingClient) : IAutomaticTaxFa
{ {
if (parameters.Subscriber is User) if (parameters.Subscriber is User)
{ {
return new PersonalUseAutomaticTaxStrategy(); return new PersonalUseAutomaticTaxStrategy(featureService);
} }
if (parameters.PlanType.HasValue) if (parameters.PlanType.HasValue)
{ {
var plan = await pricingClient.GetPlanOrThrow(parameters.PlanType.Value); var plan = await pricingClient.GetPlanOrThrow(parameters.PlanType.Value);
return plan.CanBeUsedByBusiness return plan.CanBeUsedByBusiness
? new BusinessUseAutomaticTaxStrategy() ? new BusinessUseAutomaticTaxStrategy(featureService)
: new PersonalUseAutomaticTaxStrategy(); : new PersonalUseAutomaticTaxStrategy(featureService);
} }
var personalUsePlans = await _personalUsePlansTask.Value; var personalUsePlans = await _personalUsePlansTask.Value;
@ -40,9 +43,9 @@ public class AutomaticTaxFactory(IPricingClient pricingClient) : IAutomaticTaxFa
if (personalUsePlans.Any(x => plans.Any(y => y.PasswordManager.StripePlanId == x))) if (personalUsePlans.Any(x => plans.Any(y => y.PasswordManager.StripePlanId == x)))
{ {
return new PersonalUseAutomaticTaxStrategy(); return new PersonalUseAutomaticTaxStrategy(featureService);
} }
return new BusinessUseAutomaticTaxStrategy(); return new BusinessUseAutomaticTaxStrategy(featureService);
} }
} }

View File

@ -1,13 +1,19 @@
#nullable enable #nullable enable
using Bit.Core.Billing.Extensions; using Bit.Core.Billing.Extensions;
using Bit.Core.Services;
using Stripe; using Stripe;
namespace Bit.Core.Billing.Services.Implementations.AutomaticTax; namespace Bit.Core.Billing.Services.Implementations.AutomaticTax;
public class BusinessUseAutomaticTaxStrategy : IAutomaticTaxStrategy public class BusinessUseAutomaticTaxStrategy(IFeatureService featureService) : IAutomaticTaxStrategy
{ {
public SubscriptionUpdateOptions? GetUpdateOptions(Subscription subscription) public SubscriptionUpdateOptions? GetUpdateOptions(Subscription subscription)
{ {
if (!featureService.IsEnabled(FeatureFlagKeys.PM19422_AllowAutomaticTaxUpdates))
{
return null;
}
var shouldBeEnabled = ShouldBeEnabled(subscription.Customer); var shouldBeEnabled = ShouldBeEnabled(subscription.Customer);
if (subscription.AutomaticTax.Enabled == shouldBeEnabled) if (subscription.AutomaticTax.Enabled == shouldBeEnabled)
{ {
@ -36,6 +42,11 @@ public class BusinessUseAutomaticTaxStrategy : IAutomaticTaxStrategy
public void SetUpdateOptions(SubscriptionUpdateOptions options, Subscription subscription) public void SetUpdateOptions(SubscriptionUpdateOptions options, Subscription subscription)
{ {
if (!featureService.IsEnabled(FeatureFlagKeys.PM19422_AllowAutomaticTaxUpdates))
{
return;
}
var shouldBeEnabled = ShouldBeEnabled(subscription.Customer); var shouldBeEnabled = ShouldBeEnabled(subscription.Customer);
if (subscription.AutomaticTax.Enabled == shouldBeEnabled) if (subscription.AutomaticTax.Enabled == shouldBeEnabled)

View File

@ -1,10 +1,11 @@
#nullable enable #nullable enable
using Bit.Core.Billing.Extensions; using Bit.Core.Billing.Extensions;
using Bit.Core.Services;
using Stripe; using Stripe;
namespace Bit.Core.Billing.Services.Implementations.AutomaticTax; namespace Bit.Core.Billing.Services.Implementations.AutomaticTax;
public class PersonalUseAutomaticTaxStrategy : IAutomaticTaxStrategy public class PersonalUseAutomaticTaxStrategy(IFeatureService featureService) : IAutomaticTaxStrategy
{ {
public void SetCreateOptions(SubscriptionCreateOptions options, Customer customer) public void SetCreateOptions(SubscriptionCreateOptions options, Customer customer)
{ {
@ -16,6 +17,10 @@ public class PersonalUseAutomaticTaxStrategy : IAutomaticTaxStrategy
public void SetUpdateOptions(SubscriptionUpdateOptions options, Subscription subscription) public void SetUpdateOptions(SubscriptionUpdateOptions options, Subscription subscription)
{ {
if (!featureService.IsEnabled(FeatureFlagKeys.PM19422_AllowAutomaticTaxUpdates))
{
return;
}
options.AutomaticTax = new SubscriptionAutomaticTaxOptions options.AutomaticTax = new SubscriptionAutomaticTaxOptions
{ {
Enabled = ShouldBeEnabled(subscription.Customer) Enabled = ShouldBeEnabled(subscription.Customer)
@ -25,6 +30,11 @@ public class PersonalUseAutomaticTaxStrategy : IAutomaticTaxStrategy
public SubscriptionUpdateOptions? GetUpdateOptions(Subscription subscription) public SubscriptionUpdateOptions? GetUpdateOptions(Subscription subscription)
{ {
if (!featureService.IsEnabled(FeatureFlagKeys.PM19422_AllowAutomaticTaxUpdates))
{
return null;
}
if (subscription.AutomaticTax.Enabled == ShouldBeEnabled(subscription.Customer)) if (subscription.AutomaticTax.Enabled == ShouldBeEnabled(subscription.Customer))
{ {
return null; return null;

View File

@ -175,6 +175,7 @@ public static class FeatureFlagKeys
public const string WebPush = "web-push"; public const string WebPush = "web-push";
public const string AndroidImportLoginsFlow = "import-logins-flow"; public const string AndroidImportLoginsFlow = "import-logins-flow";
public const string PM19147_AutomaticTaxImprovements = "pm-19147-automatic-tax-improvements"; public const string PM19147_AutomaticTaxImprovements = "pm-19147-automatic-tax-improvements";
public const string PM19422_AllowAutomaticTaxUpdates = "pm-19422-allow-automatic-tax-updates";
public const string PM12276Breadcrumbing = "pm-12276-breadcrumbing-for-business-features"; public const string PM12276Breadcrumbing = "pm-12276-breadcrumbing-for-business-features";
public const string PM18794_ProviderPaymentMethod = "pm-18794-provider-payment-method"; public const string PM18794_ProviderPaymentMethod = "pm-18794-provider-payment-method";
public const string PM3553_MobileSimpleLoginSelfHostAlias = "simple-login-self-host-alias"; public const string PM3553_MobileSimpleLoginSelfHostAlias = "simple-login-self-host-alias";

View File

@ -130,7 +130,7 @@ public class StripePaymentService : IPaymentService
if (_featureService.IsEnabled(FeatureFlagKeys.PM19147_AutomaticTaxImprovements)) if (_featureService.IsEnabled(FeatureFlagKeys.PM19147_AutomaticTaxImprovements))
{ {
var automaticTaxParameters = new AutomaticTaxFactoryParameters(subscriber, sub.Items.Select(x => x.Price.Id)); var automaticTaxParameters = new AutomaticTaxFactoryParameters(subscriber, updatedItemOptions.Select(x => x.Price));
var automaticTaxStrategy = await _automaticTaxFactory.CreateAsync(automaticTaxParameters); var automaticTaxStrategy = await _automaticTaxFactory.CreateAsync(automaticTaxParameters);
automaticTaxStrategy.SetUpdateOptions(subUpdateOptions, sub); automaticTaxStrategy.SetUpdateOptions(subUpdateOptions, sub);
} }