diff --git a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts index d8568d15b5..8b3225882b 100644 --- a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts +++ b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts @@ -51,6 +51,7 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy showUpdatedSubscriptionStatusSection$: Observable; manageBillingFromProviderPortal = ManageBilling; isProviderManaged = false; + enableTimeThreshold: boolean; protected readonly teamsStarter = ProductTierType.TeamsStarter; @@ -60,6 +61,10 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy FeatureFlag.EnableConsolidatedBilling, ); + protected enableTimeThreshold$ = this.configService.getFeatureFlag$( + FeatureFlag.EnableTimeThreshold, + ); + constructor( private apiService: ApiService, private platformUtilsService: PlatformUtilsService, @@ -94,6 +99,7 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy this.showUpdatedSubscriptionStatusSection$ = this.configService.getFeatureFlag$( FeatureFlag.AC1795_UpdatedSubscriptionStatusSection, ); + this.enableTimeThreshold = await firstValueFrom(this.enableTimeThreshold$); } ngOnDestroy() { @@ -284,16 +290,38 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy return this.i18nService.t("subscriptionUpgrade", this.sub.seats.toString()); } } else if (this.sub.maxAutoscaleSeats === this.sub.seats && this.sub.seats != null) { - return this.i18nService.t("subscriptionMaxReached", this.sub.seats.toString()); + if (!this.enableTimeThreshold) { + return this.i18nService.t("subscriptionMaxReached", this.sub.seats.toString()); + } + const seatAdjustmentMessage = this.sub.plan.isAnnual + ? "annualSubscriptionUserSeatsMessage" + : "monthlySubscriptionUserSeatsMessage"; + return this.i18nService.t( + seatAdjustmentMessage + "subscriptionSeatMaxReached", + this.sub.seats.toString(), + ); } else if (this.userOrg.productTierType === ProductTierType.TeamsStarter) { return this.i18nService.t("subscriptionUserSeatsWithoutAdditionalSeatsOption", 10); } else if (this.sub.maxAutoscaleSeats == null) { - return this.i18nService.t("subscriptionUserSeatsUnlimitedAutoscale"); + if (!this.enableTimeThreshold) { + return this.i18nService.t("subscriptionUserSeatsUnlimitedAutoscale"); + } + + const seatAdjustmentMessage = this.sub.plan.isAnnual + ? "annualSubscriptionUserSeatsMessage" + : "monthlySubscriptionUserSeatsMessage"; + return this.i18nService.t(seatAdjustmentMessage); } else { - return this.i18nService.t( - "subscriptionUserSeatsLimitedAutoscale", - this.sub.maxAutoscaleSeats.toString(), - ); + if (!this.enableTimeThreshold) { + return this.i18nService.t( + "subscriptionUserSeatsLimitedAutoscale", + this.sub.maxAutoscaleSeats.toString(), + ); + } + const seatAdjustmentMessage = this.sub.plan.isAnnual + ? "annualSubscriptionUserSeatsMessage" + : "monthlySubscriptionUserSeatsMessage"; + return this.i18nService.t(seatAdjustmentMessage, this.sub.maxAutoscaleSeats.toString()); } } diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index b0a638ad97..4dd9962a70 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -3689,6 +3689,15 @@ } } }, + "subscriptionSeatMaxReached": { + "message": "You cannot invite more than $COUNT$ members without increasing your subscription seats.", + "placeholders": { + "count": { + "content": "$1", + "example": "50" + } + } + }, "seatsToAdd": { "message": "Seats to add" }, @@ -8489,5 +8498,11 @@ "billingHistoryDescription": { "message": "Download a CSV to obtain client details for each billing date. Prorated charges are not included in the CSV and may vary from the linked invoice. For the most accurate billing details, refer to your monthly invoices.", "description": "A paragraph on the Billing History page of the Provider Portal letting users know they can download a CSV report for their invoices that does not include prorations." + }, + "monthlySubscriptionUserSeatsMessage": { + "message": "Adjustments to your subscription will result in prorated charges to your billing totals on your next billing period. " + }, + "annualSubscriptionUserSeatsMessage": { + "message": "Adjustments to your subscription will result in prorated charges on a monthly billing cycle. " } } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 5a06dbae20..759868eef7 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -20,6 +20,7 @@ export enum FeatureFlag { EmailVerification = "email-verification", InlineMenuFieldQualification = "inline-menu-field-qualification", MemberAccessReport = "ac-2059-member-access-report", + EnableTimeThreshold = "PM-5864-dollar-threshold", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -50,6 +51,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.EmailVerification]: FALSE, [FeatureFlag.InlineMenuFieldQualification]: FALSE, [FeatureFlag.MemberAccessReport]: FALSE, + [FeatureFlag.EnableTimeThreshold]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue;