1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-05 18:12:48 -05:00

Use upgrade path to change sponsorship

Sponsorships need to be annual to match the GB add-on charge rate
This commit is contained in:
Matt Gibson
2021-11-10 14:10:30 -05:00
parent dc790dbdaf
commit 339248ffaf
7 changed files with 178 additions and 243 deletions

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using Bit.Core.Models.Table;
using Stripe;
@ -6,16 +7,28 @@ namespace Bit.Core.Models.Business
{
public abstract class SubscriptionUpdate
{
protected abstract string PlanId { get; }
protected abstract List<string> PlanIds { get; }
public abstract SubscriptionItemOptions RevertItemOptions(Subscription subscription);
public abstract SubscriptionItemOptions UpgradeItemOptions(Subscription subscription);
public abstract List<SubscriptionItemOptions> RevertItemsOptions(Subscription subscription);
public abstract List<SubscriptionItemOptions> UpgradeItemsOptions(Subscription subscription);
public bool UpdateNeeded(Subscription subscription) =>
(SubscriptionItem(subscription)?.Quantity ?? 0) != (UpgradeItemOptions(subscription).Quantity ?? 0);
public bool UpdateNeeded(Subscription subscription)
{
var upgradeItemsOptions = UpgradeItemsOptions(subscription);
foreach (var upgradeItemOptions in upgradeItemsOptions)
{
var upgradeQuantity = upgradeItemOptions.Quantity ?? 0;
var existingQuantity = SubscriptionItem(subscription, upgradeItemOptions.Plan)?.Quantity ?? 0;
if (upgradeQuantity != existingQuantity)
{
return true;
}
}
return false;
}
protected SubscriptionItem SubscriptionItem(Subscription subscription) =>
subscription.Items?.Data?.FirstOrDefault(i => i.Plan.Id == PlanId);
protected static SubscriptionItem SubscriptionItem(Subscription subscription, string planId) =>
subscription.Items?.Data?.FirstOrDefault(i => i.Plan.Id == planId);
}
@ -24,7 +37,7 @@ namespace Bit.Core.Models.Business
private readonly Organization _organization;
private readonly StaticStore.Plan _plan;
private readonly long? _additionalSeats;
protected override string PlanId => _plan.StripeSeatPlanId;
protected override List<string> PlanIds => new() { _plan.StripeSeatPlanId };
public SeatSubscriptionUpdate(Organization organization, StaticStore.Plan plan, long? additionalSeats)
{
@ -33,27 +46,33 @@ namespace Bit.Core.Models.Business
_additionalSeats = additionalSeats;
}
public override SubscriptionItemOptions UpgradeItemOptions(Subscription subscription)
public override List<SubscriptionItemOptions> UpgradeItemsOptions(Subscription subscription)
{
var item = SubscriptionItem(subscription);
return new SubscriptionItemOptions
var item = SubscriptionItem(subscription, PlanIds.Single());
return new()
{
Id = item?.Id,
Plan = PlanId,
Quantity = _additionalSeats,
Deleted = (item?.Id != null && _additionalSeats == 0) ? true : (bool?)null,
new SubscriptionItemOptions
{
Id = item?.Id,
Plan = PlanIds.Single(),
Quantity = _additionalSeats,
Deleted = (item?.Id != null && _additionalSeats == 0) ? true : (bool?)null,
}
};
}
public override SubscriptionItemOptions RevertItemOptions(Subscription subscription)
public override List<SubscriptionItemOptions> RevertItemsOptions(Subscription subscription)
{
var item = SubscriptionItem(subscription);
return new SubscriptionItemOptions
var item = SubscriptionItem(subscription, PlanIds.Single());
return new()
{
Id = item?.Id,
Plan = PlanId,
Quantity = _organization.Seats,
Deleted = item?.Id != null ? true : (bool?)null,
new SubscriptionItemOptions
{
Id = item?.Id,
Plan = PlanIds.Single(),
Quantity = _organization.Seats,
Deleted = item?.Id != null ? true : (bool?)null,
}
};
}
}
@ -62,7 +81,7 @@ namespace Bit.Core.Models.Business
{
private readonly string _plan;
private readonly long? _additionalStorage;
protected override string PlanId => _plan;
protected override List<string> PlanIds => new() { _plan };
public StorageSubscriptionUpdate(string plan, long? additionalStorage)
{
@ -70,28 +89,102 @@ namespace Bit.Core.Models.Business
_additionalStorage = additionalStorage;
}
public override SubscriptionItemOptions UpgradeItemOptions(Subscription subscription)
public override List<SubscriptionItemOptions> UpgradeItemsOptions(Subscription subscription)
{
var item = SubscriptionItem(subscription);
return new SubscriptionItemOptions
var item = SubscriptionItem(subscription, PlanIds.Single());
return new()
{
Id = item?.Id,
Plan = _plan,
Quantity = _additionalStorage,
Deleted = (item?.Id != null && _additionalStorage == 0) ? true : (bool?)null,
new SubscriptionItemOptions
{
Id = item?.Id,
Plan = _plan,
Quantity = _additionalStorage,
Deleted = (item?.Id != null && _additionalStorage == 0) ? true : (bool?)null,
}
};
}
public override SubscriptionItemOptions RevertItemOptions(Subscription subscription)
public override List<SubscriptionItemOptions> RevertItemsOptions(Subscription subscription)
{
var item = SubscriptionItem(subscription);
return new SubscriptionItemOptions
var item = SubscriptionItem(subscription, PlanIds.Single());
return new()
{
Id = item?.Id,
Plan = _plan,
Quantity = item?.Quantity ?? 0,
Deleted = item?.Id != null ? true : (bool?)null,
new SubscriptionItemOptions
{
Id = item?.Id,
Plan = _plan,
Quantity = item?.Quantity ?? 0,
Deleted = item?.Id != null ? true : (bool?)null,
}
};
}
}
public class SponsorOrganizationSubscriptionUpdate : SubscriptionUpdate
{
private string _existingPlanStripeId;
private string _sponsoredPlanStripeId;
private bool _applySponsorship;
protected override List<string> PlanIds => new() { _existingPlanStripeId, _sponsoredPlanStripeId };
public SponsorOrganizationSubscriptionUpdate(StaticStore.Plan existingPlan, StaticStore.SponsoredPlan sponsoredPlan, bool applySponsorship)
{
_existingPlanStripeId = existingPlan.StripePlanId;
_sponsoredPlanStripeId = sponsoredPlan.StripePlanId;
}
public override List<SubscriptionItemOptions> RevertItemsOptions(Subscription subscription)
{
return new()
{
new SubscriptionItemOptions
{
Id = AddStripeItem(subscription)?.Id,
Plan = AddStripePlanId,
Quantity = 0,
Deleted = true,
},
new SubscriptionItemOptions
{
Id = RemoveStripeItem(subscription)?.Id,
Plan = RemoveStripePlanId,
Quantity = 1,
Deleted = false,
},
};
}
public override List<SubscriptionItemOptions> UpgradeItemsOptions(Subscription subscription)
{
return new()
{
new SubscriptionItemOptions
{
Id = RemoveStripeItem(subscription)?.Id,
Plan = RemoveStripePlanId,
Quantity = 0,
Deleted = true,
},
new SubscriptionItemOptions
{
Id = AddStripeItem(subscription)?.Id,
Plan = AddStripePlanId,
Quantity = 1,
Deleted = false,
},
};
}
private string RemoveStripePlanId => _applySponsorship ? _existingPlanStripeId : _sponsoredPlanStripeId;
private string AddStripePlanId => _applySponsorship ? _sponsoredPlanStripeId : _existingPlanStripeId;
private Stripe.SubscriptionItem RemoveStripeItem(Subscription subscription) =>
_applySponsorship ?
SubscriptionItem(subscription, _existingPlanStripeId) :
SubscriptionItem(subscription, _sponsoredPlanStripeId);
private Stripe.SubscriptionItem AddStripeItem(Subscription subscription) =>
_applySponsorship ?
SubscriptionItem(subscription, _sponsoredPlanStripeId) :
SubscriptionItem(subscription, _existingPlanStripeId);
}
}