1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-01 08:02:49 -05:00

[AC-1910] Allocate seats to a provider organization (#3936)

* Add endpoint to update a provider organization's seats for consolidated billing.

* Fixed failing tests
This commit is contained in:
Alex Morask
2024-03-29 11:18:10 -04:00
committed by GitHub
parent c53e5eeab3
commit e2cb406a95
28 changed files with 1108 additions and 68 deletions

View File

@ -1,4 +1,5 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Models.Business;
@ -28,6 +29,12 @@ public interface IPaymentService
int newlyPurchasedAdditionalStorage,
DateTime? prorationDate = null);
Task<string> AdjustSeatsAsync(Organization organization, Plan plan, int additionalSeats, DateTime? prorationDate = null);
Task<string> AdjustSeats(
Provider provider,
Plan plan,
int currentlySubscribedSeats,
int newlySubscribedSeats,
DateTime? prorationDate = null);
Task<string> AdjustSmSeatsAsync(Organization organization, Plan plan, int additionalSeats, DateTime? prorationDate = null);
Task<string> AdjustStorageAsync(IStorableSubscriber storableSubscriber, int additionalStorage, string storagePlanId, DateTime? prorationDate = null);

View File

@ -1,4 +1,5 @@
using Bit.Core.AdminConsole.Entities;
using Bit.Core.AdminConsole.Entities.Provider;
using Bit.Core.Billing.Constants;
using Bit.Core.Entities;
using Bit.Core.Enums;
@ -757,14 +758,14 @@ public class StripePaymentService : IPaymentService
}).ToList();
}
private async Task<string> FinalizeSubscriptionChangeAsync(IStorableSubscriber storableSubscriber,
private async Task<string> FinalizeSubscriptionChangeAsync(ISubscriber subscriber,
SubscriptionUpdate subscriptionUpdate, DateTime? prorationDate, bool invoiceNow = false)
{
// remember, when in doubt, throw
var subGetOptions = new SubscriptionGetOptions();
// subGetOptions.AddExpand("customer");
subGetOptions.AddExpand("customer.tax");
var sub = await _stripeAdapter.SubscriptionGetAsync(storableSubscriber.GatewaySubscriptionId, subGetOptions);
var sub = await _stripeAdapter.SubscriptionGetAsync(subscriber.GatewaySubscriptionId, subGetOptions);
if (sub == null)
{
throw new GatewayException("Subscription not found.");
@ -792,8 +793,8 @@ public class StripePaymentService : IPaymentService
{
var upcomingInvoiceWithChanges = await _stripeAdapter.InvoiceUpcomingAsync(new UpcomingInvoiceOptions
{
Customer = storableSubscriber.GatewayCustomerId,
Subscription = storableSubscriber.GatewaySubscriptionId,
Customer = subscriber.GatewayCustomerId,
Subscription = subscriber.GatewaySubscriptionId,
SubscriptionItems = ToInvoiceSubscriptionItemOptions(updatedItemOptions),
SubscriptionProrationBehavior = Constants.CreateProrations,
SubscriptionProrationDate = prorationDate,
@ -862,7 +863,7 @@ public class StripePaymentService : IPaymentService
{
if (chargeNow)
{
paymentIntentClientSecret = await PayInvoiceAfterSubscriptionChangeAsync(storableSubscriber, invoice);
paymentIntentClientSecret = await PayInvoiceAfterSubscriptionChangeAsync(subscriber, invoice);
}
else
{
@ -943,6 +944,17 @@ public class StripePaymentService : IPaymentService
return FinalizeSubscriptionChangeAsync(organization, new SeatSubscriptionUpdate(organization, plan, additionalSeats), prorationDate);
}
public Task<string> AdjustSeats(
Provider provider,
StaticStore.Plan plan,
int currentlySubscribedSeats,
int newlySubscribedSeats,
DateTime? prorationDate = null)
=> FinalizeSubscriptionChangeAsync(
provider,
new ProviderSubscriptionUpdate(plan.Type, currentlySubscribedSeats, newlySubscribedSeats),
prorationDate);
public Task<string> AdjustSmSeatsAsync(Organization organization, StaticStore.Plan plan, int additionalSeats, DateTime? prorationDate = null)
{
return FinalizeSubscriptionChangeAsync(organization, new SmSeatSubscriptionUpdate(organization, plan, additionalSeats), prorationDate);