mirror of
https://github.com/bitwarden/server.git
synced 2025-04-05 21:18:13 -05:00
[PM-15814]Alert owners of reseller-managed orgs to renewal events (#5193)
* Changes for the admin console alert Signed-off-by: Cy Okeke <cokeke@bitwarden.com> * Fix the failing test Signed-off-by: Cy Okeke <cokeke@bitwarden.com> * Add the feature flag Signed-off-by: Cy Okeke <cokeke@bitwarden.com> --------- Signed-off-by: Cy Okeke <cokeke@bitwarden.com>
This commit is contained in:
parent
83404efebd
commit
d924c6721a
@ -7,7 +7,11 @@ public record OrganizationMetadataResponse(
|
|||||||
bool IsManaged,
|
bool IsManaged,
|
||||||
bool IsOnSecretsManagerStandalone,
|
bool IsOnSecretsManagerStandalone,
|
||||||
bool IsSubscriptionUnpaid,
|
bool IsSubscriptionUnpaid,
|
||||||
bool HasSubscription)
|
bool HasSubscription,
|
||||||
|
bool HasOpenInvoice,
|
||||||
|
DateTime? InvoiceDueDate,
|
||||||
|
DateTime? InvoiceCreatedDate,
|
||||||
|
DateTime? SubPeriodEndDate)
|
||||||
{
|
{
|
||||||
public static OrganizationMetadataResponse From(OrganizationMetadata metadata)
|
public static OrganizationMetadataResponse From(OrganizationMetadata metadata)
|
||||||
=> new(
|
=> new(
|
||||||
@ -15,5 +19,9 @@ public record OrganizationMetadataResponse(
|
|||||||
metadata.IsManaged,
|
metadata.IsManaged,
|
||||||
metadata.IsOnSecretsManagerStandalone,
|
metadata.IsOnSecretsManagerStandalone,
|
||||||
metadata.IsSubscriptionUnpaid,
|
metadata.IsSubscriptionUnpaid,
|
||||||
metadata.HasSubscription);
|
metadata.HasSubscription,
|
||||||
|
metadata.HasOpenInvoice,
|
||||||
|
metadata.InvoiceDueDate,
|
||||||
|
metadata.InvoiceCreatedDate,
|
||||||
|
metadata.SubPeriodEndDate);
|
||||||
}
|
}
|
||||||
|
@ -5,4 +5,8 @@ public record OrganizationMetadata(
|
|||||||
bool IsManaged,
|
bool IsManaged,
|
||||||
bool IsOnSecretsManagerStandalone,
|
bool IsOnSecretsManagerStandalone,
|
||||||
bool IsSubscriptionUnpaid,
|
bool IsSubscriptionUnpaid,
|
||||||
bool HasSubscription);
|
bool HasSubscription,
|
||||||
|
bool HasOpenInvoice,
|
||||||
|
DateTime? InvoiceDueDate,
|
||||||
|
DateTime? InvoiceCreatedDate,
|
||||||
|
DateTime? SubPeriodEndDate);
|
||||||
|
@ -68,19 +68,25 @@ public class OrganizationBillingService(
|
|||||||
if (string.IsNullOrWhiteSpace(organization.GatewaySubscriptionId))
|
if (string.IsNullOrWhiteSpace(organization.GatewaySubscriptionId))
|
||||||
{
|
{
|
||||||
return new OrganizationMetadata(isEligibleForSelfHost, isManaged, false,
|
return new OrganizationMetadata(isEligibleForSelfHost, isManaged, false,
|
||||||
false, false);
|
false, false, false, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var customer = await subscriberService.GetCustomer(organization,
|
var customer = await subscriberService.GetCustomer(organization,
|
||||||
new CustomerGetOptions { Expand = ["discount.coupon.applies_to"] });
|
new CustomerGetOptions { Expand = ["discount.coupon.applies_to"] });
|
||||||
|
|
||||||
var subscription = await subscriberService.GetSubscription(organization);
|
var subscription = await subscriberService.GetSubscription(organization);
|
||||||
|
|
||||||
var isOnSecretsManagerStandalone = IsOnSecretsManagerStandalone(organization, customer, subscription);
|
var isOnSecretsManagerStandalone = IsOnSecretsManagerStandalone(organization, customer, subscription);
|
||||||
var isSubscriptionUnpaid = IsSubscriptionUnpaid(subscription);
|
var isSubscriptionUnpaid = IsSubscriptionUnpaid(subscription);
|
||||||
var hasSubscription = true;
|
var hasSubscription = true;
|
||||||
|
var openInvoice = await HasOpenInvoiceAsync(subscription);
|
||||||
|
var hasOpenInvoice = openInvoice.HasOpenInvoice;
|
||||||
|
var invoiceDueDate = openInvoice.DueDate;
|
||||||
|
var invoiceCreatedDate = openInvoice.CreatedDate;
|
||||||
|
var subPeriodEndDate = subscription?.CurrentPeriodEnd;
|
||||||
|
|
||||||
return new OrganizationMetadata(isEligibleForSelfHost, isManaged, isOnSecretsManagerStandalone,
|
return new OrganizationMetadata(isEligibleForSelfHost, isManaged, isOnSecretsManagerStandalone,
|
||||||
isSubscriptionUnpaid, hasSubscription);
|
isSubscriptionUnpaid, hasSubscription, hasOpenInvoice, invoiceDueDate, invoiceCreatedDate, subPeriodEndDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdatePaymentMethod(
|
public async Task UpdatePaymentMethod(
|
||||||
@ -393,6 +399,18 @@ public class OrganizationBillingService(
|
|||||||
return subscription.Status == "unpaid";
|
return subscription.Status == "unpaid";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<(bool HasOpenInvoice, DateTime? CreatedDate, DateTime? DueDate)> HasOpenInvoiceAsync(Subscription subscription)
|
||||||
|
{
|
||||||
|
if (subscription?.LatestInvoiceId == null)
|
||||||
|
{
|
||||||
|
return (false, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var invoice = await stripeAdapter.InvoiceGetAsync(subscription.LatestInvoiceId, new InvoiceGetOptions());
|
||||||
|
|
||||||
|
return invoice?.Status == "open"
|
||||||
|
? (true, invoice.Created, invoice.DueDate)
|
||||||
|
: (false, null, null);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
@ -163,6 +163,7 @@ public static class FeatureFlagKeys
|
|||||||
public const string AuthenticatorSynciOS = "enable-authenticator-sync-ios";
|
public const string AuthenticatorSynciOS = "enable-authenticator-sync-ios";
|
||||||
public const string AuthenticatorSyncAndroid = "enable-authenticator-sync-android";
|
public const string AuthenticatorSyncAndroid = "enable-authenticator-sync-android";
|
||||||
public const string AppReviewPrompt = "app-review-prompt";
|
public const string AppReviewPrompt = "app-review-prompt";
|
||||||
|
public const string ResellerManagedOrgAlert = "PM-15814-alert-owners-of-reseller-managed-orgs";
|
||||||
|
|
||||||
public static List<string> GetAllKeys()
|
public static List<string> GetAllKeys()
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ public class OrganizationBillingControllerTests
|
|||||||
{
|
{
|
||||||
sutProvider.GetDependency<ICurrentContext>().OrganizationUser(organizationId).Returns(true);
|
sutProvider.GetDependency<ICurrentContext>().OrganizationUser(organizationId).Returns(true);
|
||||||
sutProvider.GetDependency<IOrganizationBillingService>().GetMetadata(organizationId)
|
sutProvider.GetDependency<IOrganizationBillingService>().GetMetadata(organizationId)
|
||||||
.Returns(new OrganizationMetadata(true, true, true, true, true));
|
.Returns(new OrganizationMetadata(true, true, true, true, true, true, null, null, null));
|
||||||
|
|
||||||
var result = await sutProvider.Sut.GetMetadataAsync(organizationId);
|
var result = await sutProvider.Sut.GetMetadataAsync(organizationId);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user