1
0
mirror of https://github.com/bitwarden/server synced 2026-02-20 03:13:35 +00:00

[PM-24555] Remove Code for PM-21092 (#6198)

This commit is contained in:
Stephon Brown
2025-08-21 16:24:16 -04:00
committed by GitHub
parent c519fa43c6
commit 91bb3c1e68
10 changed files with 55 additions and 212 deletions

View File

@@ -1,7 +1,7 @@
// FIXME: Update this file to be null safe and then delete the line below
#nullable disable
using Bit.Core;
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Repositories;
@@ -18,7 +18,6 @@ using Event = Stripe.Event;
namespace Bit.Billing.Services.Implementations;
public class UpcomingInvoiceHandler(
IFeatureService featureService,
ILogger<StripeEventProcessor> logger,
IMailService mailService,
IOrganizationRepository organizationRepository,
@@ -48,8 +47,6 @@ public class UpcomingInvoiceHandler(
var (organizationId, userId, providerId) = stripeEventUtilityService.GetIdsFromMetadata(subscription.Metadata);
var setNonUSBusinessUseToReverseCharge = featureService.IsEnabled(FeatureFlagKeys.PM21092_SetNonUSBusinessUseToReverseCharge);
if (organizationId.HasValue)
{
var organization = await organizationRepository.GetByIdAsync(organizationId.Value);
@@ -59,7 +56,7 @@ public class UpcomingInvoiceHandler(
return;
}
await AlignOrganizationTaxConcernsAsync(organization, subscription, parsedEvent.Id, setNonUSBusinessUseToReverseCharge);
await AlignOrganizationTaxConcernsAsync(organization, subscription, parsedEvent.Id);
var plan = await pricingClient.GetPlanOrThrow(organization.PlanType);
@@ -138,7 +135,7 @@ public class UpcomingInvoiceHandler(
return;
}
await AlignProviderTaxConcernsAsync(provider, subscription, parsedEvent.Id, setNonUSBusinessUseToReverseCharge);
await AlignProviderTaxConcernsAsync(provider, subscription, parsedEvent.Id);
await SendUpcomingInvoiceEmailsAsync(new List<string> { provider.BillingEmail }, invoice);
}
@@ -164,45 +161,30 @@ public class UpcomingInvoiceHandler(
private async Task AlignOrganizationTaxConcernsAsync(
Organization organization,
Subscription subscription,
string eventId,
bool setNonUSBusinessUseToReverseCharge)
string eventId)
{
var nonUSBusinessUse =
organization.PlanType.GetProductTier() != ProductTierType.Families &&
subscription.Customer.Address.Country != "US";
bool setAutomaticTaxToEnabled;
if (setNonUSBusinessUseToReverseCharge)
if (nonUSBusinessUse && subscription.Customer.TaxExempt != StripeConstants.TaxExempt.Reverse)
{
if (nonUSBusinessUse && subscription.Customer.TaxExempt != StripeConstants.TaxExempt.Reverse)
try
{
try
{
await stripeFacade.UpdateCustomer(subscription.CustomerId,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.Reverse });
}
catch (Exception exception)
{
logger.LogError(
exception,
"Failed to set organization's ({OrganizationID}) to reverse tax exemption while processing event with ID {EventID}",
organization.Id,
eventId);
}
await stripeFacade.UpdateCustomer(subscription.CustomerId,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.Reverse });
}
catch (Exception exception)
{
logger.LogError(
exception,
"Failed to set organization's ({OrganizationID}) to reverse tax exemption while processing event with ID {EventID}",
organization.Id,
eventId);
}
setAutomaticTaxToEnabled = true;
}
else
{
setAutomaticTaxToEnabled =
subscription.Customer.HasRecognizedTaxLocation() &&
(subscription.Customer.Address.Country == "US" ||
(nonUSBusinessUse && subscription.Customer.TaxIds.Any()));
}
if (!subscription.AutomaticTax.Enabled && setAutomaticTaxToEnabled)
if (!subscription.AutomaticTax.Enabled)
{
try
{
@@ -226,41 +208,27 @@ public class UpcomingInvoiceHandler(
private async Task AlignProviderTaxConcernsAsync(
Provider provider,
Subscription subscription,
string eventId,
bool setNonUSBusinessUseToReverseCharge)
string eventId)
{
bool setAutomaticTaxToEnabled;
if (setNonUSBusinessUseToReverseCharge)
if (subscription.Customer.Address.Country != "US" &&
subscription.Customer.TaxExempt != StripeConstants.TaxExempt.Reverse)
{
if (subscription.Customer.Address.Country != "US" && subscription.Customer.TaxExempt != StripeConstants.TaxExempt.Reverse)
try
{
try
{
await stripeFacade.UpdateCustomer(subscription.CustomerId,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.Reverse });
}
catch (Exception exception)
{
logger.LogError(
exception,
"Failed to set provider's ({ProviderID}) to reverse tax exemption while processing event with ID {EventID}",
provider.Id,
eventId);
}
await stripeFacade.UpdateCustomer(subscription.CustomerId,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.Reverse });
}
catch (Exception exception)
{
logger.LogError(
exception,
"Failed to set provider's ({ProviderID}) to reverse tax exemption while processing event with ID {EventID}",
provider.Id,
eventId);
}
setAutomaticTaxToEnabled = true;
}
else
{
setAutomaticTaxToEnabled =
subscription.Customer.HasRecognizedTaxLocation() &&
(subscription.Customer.Address.Country == "US" ||
subscription.Customer.TaxIds.Any());
}
if (!subscription.AutomaticTax.Enabled && setAutomaticTaxToEnabled)
if (!subscription.AutomaticTax.Enabled)
{
try
{

View File

@@ -26,7 +26,6 @@ namespace Bit.Core.Billing.Organizations.Services;
public class OrganizationBillingService(
IBraintreeGateway braintreeGateway,
IFeatureService featureService,
IGlobalSettings globalSettings,
ILogger<OrganizationBillingService> logger,
IOrganizationRepository organizationRepository,
@@ -273,11 +272,9 @@ public class OrganizationBillingService(
ValidateLocation = StripeConstants.ValidateTaxLocationTiming.Immediately
};
var setNonUSBusinessUseToReverseCharge =
featureService.IsEnabled(FeatureFlagKeys.PM21092_SetNonUSBusinessUseToReverseCharge);
if (setNonUSBusinessUseToReverseCharge &&
planType.GetProductTier() is not ProductTierType.Free and not ProductTierType.Families &&
if (planType.GetProductTier() is not ProductTierType.Free and not ProductTierType.Families &&
customerSetup.TaxInformation.Country != "US")
{
customerCreateOptions.TaxExempt = StripeConstants.TaxExempt.Reverse;
@@ -491,24 +488,10 @@ public class OrganizationBillingService(
};
}
var setNonUSBusinessUseToReverseCharge =
featureService.IsEnabled(FeatureFlagKeys.PM21092_SetNonUSBusinessUseToReverseCharge);
if (setNonUSBusinessUseToReverseCharge && customer.HasBillingLocation())
if (customer.HasBillingLocation())
{
subscriptionCreateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
}
else if (customer.HasRecognizedTaxLocation())
{
subscriptionCreateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions
{
Enabled =
subscriptionSetup.PlanType.GetProductTier() == ProductTierType.Families ||
customer.Address.Country == "US" ||
customer.TaxIds.Any()
};
}
return await stripeAdapter.SubscriptionCreateAsync(subscriptionCreateOptions);
}
@@ -519,9 +502,7 @@ public class OrganizationBillingService(
var customer = await subscriberService.GetCustomerOrThrow(organization,
new CustomerGetOptions { Expand = ["tax", "tax_ids"] });
var setNonUSBusinessUseToReverseCharge = featureService.IsEnabled(FeatureFlagKeys.PM21092_SetNonUSBusinessUseToReverseCharge);
if (!setNonUSBusinessUseToReverseCharge || subscriptionSetup.PlanType.GetProductTier() is
if (subscriptionSetup.PlanType.GetProductTier() is
not (ProductTierType.Teams or
ProductTierType.TeamsStarter or
ProductTierType.Enterprise))

View File

@@ -33,7 +33,6 @@ using static StripeConstants;
public class SubscriberService(
IBraintreeGateway braintreeGateway,
IFeatureService featureService,
IGlobalSettings globalSettings,
ILogger<SubscriberService> logger,
IOrganizationRepository organizationRepository,
@@ -802,28 +801,27 @@ public class SubscriberService(
_ => false
};
var setNonUSBusinessUseToReverseCharge =
featureService.IsEnabled(FeatureFlagKeys.PM21092_SetNonUSBusinessUseToReverseCharge);
if (setNonUSBusinessUseToReverseCharge && isBusinessUseSubscriber)
if (isBusinessUseSubscriber)
{
switch (customer)
{
case
{
Address.Country: not "US",
TaxExempt: not StripeConstants.TaxExempt.Reverse
TaxExempt: not TaxExempt.Reverse
}:
await stripeAdapter.CustomerUpdateAsync(customer.Id,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.Reverse });
new CustomerUpdateOptions { TaxExempt = TaxExempt.Reverse });
break;
case
{
Address.Country: "US",
TaxExempt: StripeConstants.TaxExempt.Reverse
TaxExempt: TaxExempt.Reverse
}:
await stripeAdapter.CustomerUpdateAsync(customer.Id,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.None });
new CustomerUpdateOptions { TaxExempt = TaxExempt.None });
break;
}

View File

@@ -154,7 +154,6 @@ public static class FeatureFlagKeys
public const string PM19422_AllowAutomaticTaxUpdates = "pm-19422-allow-automatic-tax-updates";
public const string PM199566_UpdateMSPToChargeAutomatically = "pm-199566-update-msp-to-charge-automatically";
public const string UseOrganizationWarningsService = "use-organization-warnings-service";
public const string PM21092_SetNonUSBusinessUseToReverseCharge = "pm-21092-set-non-us-business-use-to-reverse-charge";
public const string PM21881_ManagePaymentDetailsOutsideCheckout = "pm-21881-manage-payment-details-outside-checkout";
public const string PM21821_ProviderPortalTakeover = "pm-21821-provider-portal-takeover";
public const string PM22415_TaxIDWarnings = "pm-22415-tax-id-warnings";

View File

@@ -1,11 +1,10 @@
// FIXME: Update this file to be null safe and then delete the line below
#nullable disable
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.AdminConsole.Models.Business;
using Bit.Core.Billing.Constants;
using Bit.Core.Billing.Enums;
using Bit.Core.Billing.Extensions;
using Bit.Core.Billing.Models;
using Bit.Core.Billing.Organizations.Models;
@@ -136,69 +135,17 @@ public class StripePaymentService : IPaymentService
if (subscriptionUpdate is CompleteSubscriptionUpdate)
{
var setNonUSBusinessUseToReverseCharge =
_featureService.IsEnabled(FeatureFlagKeys.PM21092_SetNonUSBusinessUseToReverseCharge);
if (setNonUSBusinessUseToReverseCharge)
{
if (sub.Customer is
{
Address.Country: not "US",
TaxExempt: not StripeConstants.TaxExempt.Reverse
})
if (sub.Customer is
{
await _stripeAdapter.CustomerUpdateAsync(sub.CustomerId,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.Reverse });
}
subUpdateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
}
else if (sub.Customer.HasRecognizedTaxLocation())
Address.Country: not "US",
TaxExempt: not StripeConstants.TaxExempt.Reverse
})
{
switch (subscriber)
{
case User:
{
subUpdateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
break;
}
case Organization:
{
if (sub.Customer.Address.Country == "US")
{
subUpdateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
}
else
{
var familyPriceIds = (await Task.WhenAll(
_pricingClient.GetPlanOrThrow(PlanType.FamiliesAnnually2019),
_pricingClient.GetPlanOrThrow(PlanType.FamiliesAnnually)))
.Select(plan => plan.PasswordManager.StripePlanId);
var updateIsForPersonalUse = updatedItemOptions
.Select(option => option.Price)
.Intersect(familyPriceIds)
.Any();
subUpdateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions
{
Enabled = updateIsForPersonalUse || sub.Customer.TaxIds.Any()
};
}
break;
}
case Provider:
{
subUpdateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions
{
Enabled = sub.Customer.Address.Country == "US" ||
sub.Customer.TaxIds.Any()
};
break;
}
}
await _stripeAdapter.CustomerUpdateAsync(sub.CustomerId,
new CustomerUpdateOptions { TaxExempt = StripeConstants.TaxExempt.Reverse });
}
subUpdateOptions.AutomaticTax = new SubscriptionAutomaticTaxOptions { Enabled = true };
}
if (!subscriptionUpdate.UpdateNeeded(sub))