1
0
mirror of https://github.com/bitwarden/server.git synced 2025-06-30 07:36:14 -05:00

[PM-12601] Add discount to MSP during creation in Admin Portal (#5391)

* Add Provider DiscountId to database and Stripe customer

* Fix tests

* Add missing EF migrations

* Run dotnet format
This commit is contained in:
Alex Morask
2025-03-05 14:59:15 -05:00
committed by GitHub
parent 10756ca35e
commit fa90991270
21 changed files with 9356 additions and 36 deletions

View File

@ -10,6 +10,9 @@ public class CreateMspProviderModel : IValidatableObject
[Display(Name = "Owner Email")]
public string OwnerEmail { get; set; }
[Display(Name = "Subscription Discount")]
public string DiscountId { get; set; }
[Display(Name = "Teams (Monthly) Seat Minimum")]
public int TeamsMonthlySeatMinimum { get; set; }
@ -20,7 +23,8 @@ public class CreateMspProviderModel : IValidatableObject
{
return new Provider
{
Type = ProviderType.Msp
Type = ProviderType.Msp,
DiscountId = DiscountId
};
}

View File

@ -1,3 +1,4 @@
@using Bit.Core.Billing.Constants
@model CreateMspProviderModel
@{
@ -12,6 +13,19 @@
<label asp-for="OwnerEmail" class="form-label"></label>
<input type="text" class="form-control" asp-for="OwnerEmail">
</div>
<div class="mb-3">
@{
var selectList = new List<SelectListItem>
{
new ("No discount", string.Empty, true),
new ("20% - Open", StripeConstants.CouponIDs.MSPDiscounts.Open),
new ("35% - Silver", StripeConstants.CouponIDs.MSPDiscounts.Silver),
new ("50% - Gold", StripeConstants.CouponIDs.MSPDiscounts.Gold)
};
}
<label asp-for="DiscountId" class="form-label"></label>
<select class="form-select" asp-for="DiscountId" asp-items="selectList"></select>
</div>
<div class="row">
<div class="col-sm">
<div class="mb-3">

View File

@ -35,6 +35,7 @@ public class Provider : ITableObject<Guid>, ISubscriber
public GatewayType? Gateway { get; set; }
public string? GatewayCustomerId { get; set; }
public string? GatewaySubscriptionId { get; set; }
public string? DiscountId { get; set; }
public string? BillingEmailAddress() => BillingEmail?.ToLowerInvariant().Trim();

View File

@ -18,8 +18,15 @@ public static class StripeConstants
public static class CouponIDs
{
public const string MSPDiscount35 = "msp-discount-35";
public const string LegacyMSPDiscount = "msp-discount-35";
public const string SecretsManagerStandalone = "sm-standalone";
public static class MSPDiscounts
{
public const string Open = "msp-open-discount";
public const string Silver = "msp-silver-discount";
public const string Gold = "msp-gold-discount";
}
}
public static class ErrorCodes

View File

@ -254,7 +254,7 @@ public class ProviderMigrator(
await stripeAdapter.CustomerUpdateAsync(customer.Id, new CustomerUpdateOptions
{
Coupon = StripeConstants.CouponIDs.MSPDiscount35
Coupon = StripeConstants.CouponIDs.LegacyMSPDiscount
});
provider.GatewayCustomerId = customer.Id;

View File

@ -46,7 +46,8 @@ public class OrganizationSale
var customerSetup = new CustomerSetup
{
Coupon = signup.IsFromProvider
? StripeConstants.CouponIDs.MSPDiscount35
// TODO: Remove when last of the legacy providers has been migrated.
? StripeConstants.CouponIDs.LegacyMSPDiscount
: signup.IsFromSecretsManagerTrial
? StripeConstants.CouponIDs.SecretsManagerStandalone
: null

View File

@ -17,7 +17,8 @@
@RevisionDate DATETIME2(7),
@Gateway TINYINT = 0,
@GatewayCustomerId VARCHAR(50) = NULL,
@GatewaySubscriptionId VARCHAR(50) = NULL
@GatewaySubscriptionId VARCHAR(50) = NULL,
@DiscountId VARCHAR(50) = NULL
AS
BEGIN
SET NOCOUNT ON
@ -42,7 +43,8 @@ BEGIN
[RevisionDate],
[Gateway],
[GatewayCustomerId],
[GatewaySubscriptionId]
[GatewaySubscriptionId],
[DiscountId]
)
VALUES
(
@ -64,6 +66,7 @@ BEGIN
@RevisionDate,
@Gateway,
@GatewayCustomerId,
@GatewaySubscriptionId
@GatewaySubscriptionId,
@DiscountId
)
END

View File

@ -17,7 +17,8 @@
@RevisionDate DATETIME2(7),
@Gateway TINYINT = 0,
@GatewayCustomerId VARCHAR(50) = NULL,
@GatewaySubscriptionId VARCHAR(50) = NULL
@GatewaySubscriptionId VARCHAR(50) = NULL,
@DiscountId VARCHAR(50) = NULL
AS
BEGIN
SET NOCOUNT ON
@ -42,7 +43,8 @@ BEGIN
[RevisionDate] = @RevisionDate,
[Gateway] = @Gateway,
[GatewayCustomerId] = @GatewayCustomerId,
[GatewaySubscriptionId] = @GatewaySubscriptionId
[GatewaySubscriptionId] = @GatewaySubscriptionId,
[DiscountId] = @DiscountId
WHERE
[Id] = @Id
END

View File

@ -18,5 +18,6 @@
[Gateway] TINYINT NULL,
[GatewayCustomerId] VARCHAR (50) NULL,
[GatewaySubscriptionId] VARCHAR (50) NULL,
[DiscountId] VARCHAR (50) NULL,
CONSTRAINT [PK_Provider] PRIMARY KEY CLUSTERED ([Id] ASC)
);