1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-21 12:05:42 +01:00

[PM-13717] Fix legacy credit rebate for migrated MSPs (#4906)

* Fix legacy credit rebate for migrated MSPs

* Run dotnet format
This commit is contained in:
Alex Morask 2024-10-21 08:54:06 -04:00 committed by GitHub
parent c809794642
commit 5d15750b80
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 10 deletions

View File

@ -306,21 +306,36 @@ public class ProviderMigrator(
var organizationCancellationCredit = organizationCustomers.Sum(customer => customer.Balance);
var legacyOrganizations = organizations.Where(organization =>
organization.PlanType is
PlanType.EnterpriseAnnually2020 or
PlanType.EnterpriseMonthly2020 or
PlanType.TeamsAnnually2020 or
PlanType.TeamsMonthly2020);
var legacyOrganizationCredit = legacyOrganizations.Sum(organization => organization.Seats ?? 0);
await stripeAdapter.CustomerUpdateAsync(provider.GatewayCustomerId, new CustomerUpdateOptions
await stripeAdapter.CustomerBalanceTransactionCreate(provider.GatewayCustomerId,
new CustomerBalanceTransactionCreateOptions
{
Balance = organizationCancellationCredit + legacyOrganizationCredit
Amount = organizationCancellationCredit,
Currency = "USD",
Description = "Unused, prorated time for client organization subscriptions."
});
logger.LogInformation("CB: Applied {Credit} credit to provider ({ProviderID})", organizationCancellationCredit, provider.Id);
var migrationRecords = await Task.WhenAll(organizations.Select(organization =>
clientOrganizationMigrationRecordRepository.GetByOrganizationId(organization.Id)));
var legacyOrganizationMigrationRecords = migrationRecords.Where(migrationRecord =>
migrationRecord.PlanType is
PlanType.EnterpriseAnnually2020 or
PlanType.TeamsAnnually2020);
var legacyOrganizationCredit = legacyOrganizationMigrationRecords.Sum(migrationRecord => migrationRecord.Seats) * 12 * -100;
if (legacyOrganizationCredit < 0)
{
await stripeAdapter.CustomerBalanceTransactionCreate(provider.GatewayCustomerId,
new CustomerBalanceTransactionCreateOptions
{
Amount = legacyOrganizationCredit,
Currency = "USD",
Description = "1 year rebate for legacy client organizations."
});
}
logger.LogInformation("CB: Applied {Credit} credit to provider ({ProviderID})", organizationCancellationCredit + legacyOrganizationCredit, provider.Id);
await migrationTrackerCache.UpdateTrackingStatus(provider.Id, ProviderMigrationProgress.CreditApplied);
}

View File

@ -10,6 +10,8 @@ public interface IStripeAdapter
Task<Stripe.Customer> CustomerUpdateAsync(string id, Stripe.CustomerUpdateOptions options = null);
Task<Stripe.Customer> CustomerDeleteAsync(string id);
Task<List<PaymentMethod>> CustomerListPaymentMethods(string id, CustomerListPaymentMethodsOptions options = null);
Task<CustomerBalanceTransaction> CustomerBalanceTransactionCreate(string customerId,
CustomerBalanceTransactionCreateOptions options);
Task<Stripe.Subscription> SubscriptionCreateAsync(Stripe.SubscriptionCreateOptions subscriptionCreateOptions);
Task<Stripe.Subscription> SubscriptionGetAsync(string id, Stripe.SubscriptionGetOptions options = null);
Task<List<Stripe.Subscription>> SubscriptionListAsync(StripeSubscriptionListOptions subscriptionSearchOptions);

View File

@ -18,6 +18,7 @@ public class StripeAdapter : IStripeAdapter
private readonly Stripe.PriceService _priceService;
private readonly Stripe.SetupIntentService _setupIntentService;
private readonly Stripe.TestHelpers.TestClockService _testClockService;
private readonly CustomerBalanceTransactionService _customerBalanceTransactionService;
public StripeAdapter()
{
@ -34,6 +35,7 @@ public class StripeAdapter : IStripeAdapter
_priceService = new Stripe.PriceService();
_setupIntentService = new SetupIntentService();
_testClockService = new Stripe.TestHelpers.TestClockService();
_customerBalanceTransactionService = new CustomerBalanceTransactionService();
}
public Task<Stripe.Customer> CustomerCreateAsync(Stripe.CustomerCreateOptions options)
@ -63,6 +65,10 @@ public class StripeAdapter : IStripeAdapter
return paymentMethods.Data;
}
public async Task<CustomerBalanceTransaction> CustomerBalanceTransactionCreate(string customerId,
CustomerBalanceTransactionCreateOptions options)
=> await _customerBalanceTransactionService.CreateAsync(customerId, options);
public Task<Stripe.Subscription> SubscriptionCreateAsync(Stripe.SubscriptionCreateOptions options)
{
return _subscriptionService.CreateAsync(options);