mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-16 01:21:48 +01:00
[AC-2858] Remove code supporting payment method warning banners (#10615)
* Remove errant payment method warning banner implementation * Removing unused endpoint
This commit is contained in:
parent
cfdc52ee84
commit
b030c6e27b
@ -2,17 +2,7 @@ import { DOCUMENT } from "@angular/common";
|
|||||||
import { Component, Inject, NgZone, OnDestroy, OnInit } from "@angular/core";
|
import { Component, Inject, NgZone, OnDestroy, OnInit } from "@angular/core";
|
||||||
import { NavigationEnd, Router } from "@angular/router";
|
import { NavigationEnd, Router } from "@angular/router";
|
||||||
import * as jq from "jquery";
|
import * as jq from "jquery";
|
||||||
import {
|
import { Subject, filter, firstValueFrom, map, takeUntil, timeout } from "rxjs";
|
||||||
Subject,
|
|
||||||
combineLatest,
|
|
||||||
filter,
|
|
||||||
firstValueFrom,
|
|
||||||
map,
|
|
||||||
switchMap,
|
|
||||||
takeUntil,
|
|
||||||
timeout,
|
|
||||||
timer,
|
|
||||||
} from "rxjs";
|
|
||||||
|
|
||||||
import { LogoutReason } from "@bitwarden/auth/common";
|
import { LogoutReason } from "@bitwarden/auth/common";
|
||||||
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
|
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
|
||||||
@ -25,8 +15,6 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
|
|||||||
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
||||||
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
|
||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { PaymentMethodWarningsServiceAbstraction as PaymentMethodWarningService } from "@bitwarden/common/billing/abstractions/payment-method-warnings-service.abstraction";
|
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||||
@ -58,7 +46,6 @@ import {
|
|||||||
|
|
||||||
const BroadcasterSubscriptionId = "AppComponent";
|
const BroadcasterSubscriptionId = "AppComponent";
|
||||||
const IdleTimeout = 60000 * 10; // 10 minutes
|
const IdleTimeout = 60000 * 10; // 10 minutes
|
||||||
const PaymentMethodWarningsRefresh = 60000; // 1 Minute
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-root",
|
selector: "app-root",
|
||||||
@ -69,7 +56,6 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
private idleTimer: number = null;
|
private idleTimer: number = null;
|
||||||
private isIdle = false;
|
private isIdle = false;
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
private paymentMethodWarningsRefresh$ = timer(0, PaymentMethodWarningsRefresh);
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DOCUMENT) private document: Document,
|
@Inject(DOCUMENT) private document: Document,
|
||||||
@ -98,7 +84,6 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
private dialogService: DialogService,
|
private dialogService: DialogService,
|
||||||
private biometricStateService: BiometricStateService,
|
private biometricStateService: BiometricStateService,
|
||||||
private stateEventRunnerService: StateEventRunnerService,
|
private stateEventRunnerService: StateEventRunnerService,
|
||||||
private paymentMethodWarningService: PaymentMethodWarningService,
|
|
||||||
private organizationService: InternalOrganizationServiceAbstraction,
|
private organizationService: InternalOrganizationServiceAbstraction,
|
||||||
private accountService: AccountService,
|
private accountService: AccountService,
|
||||||
) {}
|
) {}
|
||||||
@ -252,25 +237,6 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
new DisableSendPolicy(),
|
new DisableSendPolicy(),
|
||||||
new SendOptionsPolicy(),
|
new SendOptionsPolicy(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
combineLatest([
|
|
||||||
this.configService.getFeatureFlag$(FeatureFlag.ShowPaymentMethodWarningBanners),
|
|
||||||
this.paymentMethodWarningsRefresh$,
|
|
||||||
])
|
|
||||||
.pipe(
|
|
||||||
filter(([showPaymentMethodWarningBanners]) => showPaymentMethodWarningBanners),
|
|
||||||
switchMap(() => this.organizationService.memberOrganizations$),
|
|
||||||
switchMap(
|
|
||||||
async (organizations) =>
|
|
||||||
await Promise.all(
|
|
||||||
organizations.map((organization) =>
|
|
||||||
this.paymentMethodWarningService.update(organization.id),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
takeUntil(this.destroy$),
|
|
||||||
)
|
|
||||||
.subscribe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@ -328,7 +294,6 @@ export class AppComponent implements OnDestroy, OnInit {
|
|||||||
this.folderService.clear(userId),
|
this.folderService.clear(userId),
|
||||||
this.collectionService.clear(userId),
|
this.collectionService.clear(userId),
|
||||||
this.biometricStateService.logout(userId),
|
this.biometricStateService.logout(userId),
|
||||||
this.paymentMethodWarningService.clear(),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await this.stateEventRunnerService.handleEvent("logout", userId);
|
await this.stateEventRunnerService.handleEvent("logout", userId);
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
||||||
import { Component, Inject, ViewChild } from "@angular/core";
|
import { Component, Inject, ViewChild } from "@angular/core";
|
||||||
import { FormGroup } from "@angular/forms";
|
import { FormGroup } from "@angular/forms";
|
||||||
import { firstValueFrom } from "rxjs";
|
|
||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
|
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
|
||||||
import { PaymentMethodWarningsServiceAbstraction as PaymentMethodWarningService } from "@bitwarden/common/billing/abstractions/payment-method-warnings-service.abstraction";
|
|
||||||
import { PaymentMethodType } from "@bitwarden/common/billing/enums";
|
import { PaymentMethodType } from "@bitwarden/common/billing/enums";
|
||||||
import { PaymentRequest } from "@bitwarden/common/billing/models/request/payment.request";
|
import { PaymentRequest } from "@bitwarden/common/billing/models/request/payment.request";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { DialogService, ToastService } from "@bitwarden/components";
|
import { DialogService, ToastService } from "@bitwarden/components";
|
||||||
@ -46,7 +43,6 @@ export class AdjustPaymentDialogComponent {
|
|||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private organizationApiService: OrganizationApiServiceAbstraction,
|
private organizationApiService: OrganizationApiServiceAbstraction,
|
||||||
private paymentMethodWarningService: PaymentMethodWarningService,
|
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
) {
|
) {
|
||||||
@ -78,12 +74,6 @@ export class AdjustPaymentDialogComponent {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
await response;
|
await response;
|
||||||
const showPaymentMethodWarningBanners = await firstValueFrom(
|
|
||||||
this.configService.getFeatureFlag$(FeatureFlag.ShowPaymentMethodWarningBanners),
|
|
||||||
);
|
|
||||||
if (this.organizationId && showPaymentMethodWarningBanners) {
|
|
||||||
await this.paymentMethodWarningService.removeSubscriptionRisk(this.organizationId);
|
|
||||||
}
|
|
||||||
this.toastService.showToast({
|
this.toastService.showToast({
|
||||||
variant: "success",
|
variant: "success",
|
||||||
title: null,
|
title: null,
|
||||||
|
@ -3,4 +3,3 @@ export * from "./payment-method.component";
|
|||||||
export * from "./payment.component";
|
export * from "./payment.component";
|
||||||
export * from "./sm-subscribe.component";
|
export * from "./sm-subscribe.component";
|
||||||
export * from "./tax-info.component";
|
export * from "./tax-info.component";
|
||||||
export * from "./payment-method-warnings/payment-method-warnings.module";
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
<ng-container *ngFor="let warning of warnings$ | async">
|
|
||||||
<bit-banner
|
|
||||||
class="-tw-m-6 tw-flex tw-flex-col tw-pb-6"
|
|
||||||
bannerType="warning"
|
|
||||||
(onClose)="closeWarning(warning.organizationId)"
|
|
||||||
>
|
|
||||||
{{ "maintainYourSubscription" | i18n: warning.organizationName }}
|
|
||||||
<a
|
|
||||||
bitLink
|
|
||||||
linkType="contrast"
|
|
||||||
[routerLink]="['/organizations', warning.organizationId, 'billing', 'payment-method']"
|
|
||||||
>{{ "addAPaymentMethod" | i18n }}</a
|
|
||||||
>.
|
|
||||||
</bit-banner>
|
|
||||||
</ng-container>
|
|
@ -1,33 +0,0 @@
|
|||||||
import { Component } from "@angular/core";
|
|
||||||
import { map, Observable } from "rxjs";
|
|
||||||
|
|
||||||
import { PaymentMethodWarningsServiceAbstraction as PaymentMethodWarningService } from "@bitwarden/common/billing/abstractions/payment-method-warnings-service.abstraction";
|
|
||||||
|
|
||||||
type Warning = {
|
|
||||||
organizationId: string;
|
|
||||||
organizationName: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: "app-payment-method-warnings",
|
|
||||||
templateUrl: "payment-method-warnings.component.html",
|
|
||||||
})
|
|
||||||
export class PaymentMethodWarningsComponent {
|
|
||||||
constructor(private paymentMethodWarningService: PaymentMethodWarningService) {}
|
|
||||||
|
|
||||||
protected warnings$: Observable<Warning[]> =
|
|
||||||
this.paymentMethodWarningService.paymentMethodWarnings$.pipe(
|
|
||||||
map((warnings) =>
|
|
||||||
Object.entries(warnings ?? [])
|
|
||||||
.filter(([_, warning]) => warning.risksSubscriptionFailure && !warning.acknowledged)
|
|
||||||
.map(([organizationId, { organizationName }]) => ({
|
|
||||||
organizationId,
|
|
||||||
organizationName,
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
protected async closeWarning(organizationId: string): Promise<void> {
|
|
||||||
await this.paymentMethodWarningService.acknowledge(organizationId);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import { NgModule } from "@angular/core";
|
|
||||||
|
|
||||||
import { BannerModule } from "@bitwarden/components";
|
|
||||||
|
|
||||||
import { SharedModule } from "../../../shared";
|
|
||||||
|
|
||||||
import { PaymentMethodWarningsComponent } from "./payment-method-warnings.component";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [BannerModule, SharedModule],
|
|
||||||
declarations: [PaymentMethodWarningsComponent],
|
|
||||||
exports: [PaymentMethodWarningsComponent],
|
|
||||||
})
|
|
||||||
export class PaymentMethodWarningsModule {}
|
|
@ -1,9 +1,4 @@
|
|||||||
<bit-layout>
|
<bit-layout>
|
||||||
<ng-content select="app-side-nav, [slot=side-nav]" slot="side-nav"></ng-content>
|
<ng-content select="app-side-nav, [slot=side-nav]" slot="side-nav"></ng-content>
|
||||||
|
|
||||||
<app-payment-method-warnings
|
|
||||||
*ngIf="showPaymentMethodWarningBanners$ | async"
|
|
||||||
></app-payment-method-warnings>
|
|
||||||
|
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
</bit-layout>
|
</bit-layout>
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
|
||||||
import { LayoutComponent } from "@bitwarden/components";
|
import { LayoutComponent } from "@bitwarden/components";
|
||||||
|
|
||||||
import { PaymentMethodWarningsModule } from "../billing/shared";
|
|
||||||
|
|
||||||
import { ProductSwitcherModule } from "./product-switcher/product-switcher.module";
|
import { ProductSwitcherModule } from "./product-switcher/product-switcher.module";
|
||||||
import { ToggleWidthComponent } from "./toggle-width.component";
|
import { ToggleWidthComponent } from "./toggle-width.component";
|
||||||
|
|
||||||
@ -14,18 +10,8 @@ import { ToggleWidthComponent } from "./toggle-width.component";
|
|||||||
selector: "app-layout",
|
selector: "app-layout",
|
||||||
templateUrl: "web-layout.component.html",
|
templateUrl: "web-layout.component.html",
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [CommonModule, LayoutComponent, ProductSwitcherModule, ToggleWidthComponent],
|
||||||
CommonModule,
|
|
||||||
LayoutComponent,
|
|
||||||
ProductSwitcherModule,
|
|
||||||
ToggleWidthComponent,
|
|
||||||
PaymentMethodWarningsModule,
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class WebLayoutComponent {
|
export class WebLayoutComponent {
|
||||||
protected showPaymentMethodWarningBanners$ = this.configService.getFeatureFlag$(
|
constructor() {}
|
||||||
FeatureFlag.ShowPaymentMethodWarningBanners,
|
|
||||||
);
|
|
||||||
|
|
||||||
constructor(private configService: ConfigService) {}
|
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,6 @@ import { VerifyEmailTokenComponent } from "../auth/verify-email-token.component"
|
|||||||
import { VerifyRecoverDeleteComponent } from "../auth/verify-recover-delete.component";
|
import { VerifyRecoverDeleteComponent } from "../auth/verify-recover-delete.component";
|
||||||
import { SponsoredFamiliesComponent } from "../billing/settings/sponsored-families.component";
|
import { SponsoredFamiliesComponent } from "../billing/settings/sponsored-families.component";
|
||||||
import { SponsoringOrgRowComponent } from "../billing/settings/sponsoring-org-row.component";
|
import { SponsoringOrgRowComponent } from "../billing/settings/sponsoring-org-row.component";
|
||||||
import { PaymentMethodWarningsModule } from "../billing/shared";
|
|
||||||
import { DynamicAvatarComponent } from "../components/dynamic-avatar.component";
|
import { DynamicAvatarComponent } from "../components/dynamic-avatar.component";
|
||||||
import { SelectableAvatarComponent } from "../components/selectable-avatar.component";
|
import { SelectableAvatarComponent } from "../components/selectable-avatar.component";
|
||||||
import { FrontendLayoutComponent } from "../layouts/frontend-layout.component";
|
import { FrontendLayoutComponent } from "../layouts/frontend-layout.component";
|
||||||
@ -113,7 +112,6 @@ import { SharedModule } from "./shared.module";
|
|||||||
HeaderModule,
|
HeaderModule,
|
||||||
OrganizationLayoutComponent,
|
OrganizationLayoutComponent,
|
||||||
UserLayoutComponent,
|
UserLayoutComponent,
|
||||||
PaymentMethodWarningsModule,
|
|
||||||
VerifyRecoverDeleteOrgComponent,
|
VerifyRecoverDeleteOrgComponent,
|
||||||
VaultTimeoutInputComponent,
|
VaultTimeoutInputComponent,
|
||||||
],
|
],
|
||||||
|
@ -7,7 +7,6 @@ import { JslibModule } from "@bitwarden/angular/jslib.module";
|
|||||||
import { SearchModule } from "@bitwarden/components";
|
import { SearchModule } from "@bitwarden/components";
|
||||||
import { DangerZoneComponent } from "@bitwarden/web-vault/app/auth/settings/account/danger-zone.component";
|
import { DangerZoneComponent } from "@bitwarden/web-vault/app/auth/settings/account/danger-zone.component";
|
||||||
import { OrganizationPlansComponent, TaxInfoComponent } from "@bitwarden/web-vault/app/billing";
|
import { OrganizationPlansComponent, TaxInfoComponent } from "@bitwarden/web-vault/app/billing";
|
||||||
import { PaymentMethodWarningsModule } from "@bitwarden/web-vault/app/billing/shared";
|
|
||||||
import { OssModule } from "@bitwarden/web-vault/app/oss.module";
|
import { OssModule } from "@bitwarden/web-vault/app/oss.module";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -53,7 +52,6 @@ import { SetupComponent } from "./setup/setup.component";
|
|||||||
OrganizationPlansComponent,
|
OrganizationPlansComponent,
|
||||||
SearchModule,
|
SearchModule,
|
||||||
ProvidersLayoutComponent,
|
ProvidersLayoutComponent,
|
||||||
PaymentMethodWarningsModule,
|
|
||||||
TaxInfoComponent,
|
TaxInfoComponent,
|
||||||
DangerZoneComponent,
|
DangerZoneComponent,
|
||||||
ScrollingModule,
|
ScrollingModule,
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
<app-payment-method-warnings
|
|
||||||
*ngIf="showPaymentMethodWarningBanners$ | async"
|
|
||||||
></app-payment-method-warnings>
|
|
||||||
<ng-container *ngIf="loading">
|
<ng-container *ngIf="loading">
|
||||||
<i
|
<i
|
||||||
class="bwi bwi-spinner bwi-spin text-muted"
|
class="bwi bwi-spinner bwi-spin text-muted"
|
||||||
|
@ -7,7 +7,6 @@ import { first, takeUntil } from "rxjs/operators";
|
|||||||
import { ManageTaxInformationComponent } from "@bitwarden/angular/billing/components";
|
import { ManageTaxInformationComponent } from "@bitwarden/angular/billing/components";
|
||||||
import { ProviderApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/provider/provider-api.service.abstraction";
|
import { ProviderApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/provider/provider-api.service.abstraction";
|
||||||
import { ProviderSetupRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-setup.request";
|
import { ProviderSetupRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-setup.request";
|
||||||
import { TaxInformation } from "@bitwarden/common/billing/models/domain";
|
|
||||||
import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request";
|
import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request";
|
||||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||||
@ -35,12 +34,6 @@ export class SetupComponent implements OnInit, OnDestroy {
|
|||||||
billingEmail: ["", [Validators.required, Validators.email]],
|
billingEmail: ["", [Validators.required, Validators.email]],
|
||||||
});
|
});
|
||||||
|
|
||||||
protected readonly TaxInformation = TaxInformation;
|
|
||||||
|
|
||||||
protected showPaymentMethodWarningBanners$ = this.configService.getFeatureFlag$(
|
|
||||||
FeatureFlag.ShowPaymentMethodWarningBanners,
|
|
||||||
);
|
|
||||||
|
|
||||||
protected enableConsolidatedBilling$ = this.configService.getFeatureFlag$(
|
protected enableConsolidatedBilling$ = this.configService.getFeatureFlag$(
|
||||||
FeatureFlag.EnableConsolidatedBilling,
|
FeatureFlag.EnableConsolidatedBilling,
|
||||||
);
|
);
|
||||||
|
@ -123,14 +123,12 @@ import {
|
|||||||
BillingApiServiceAbstraction,
|
BillingApiServiceAbstraction,
|
||||||
BraintreeServiceAbstraction,
|
BraintreeServiceAbstraction,
|
||||||
OrganizationBillingServiceAbstraction,
|
OrganizationBillingServiceAbstraction,
|
||||||
PaymentMethodWarningsServiceAbstraction,
|
|
||||||
StripeServiceAbstraction,
|
StripeServiceAbstraction,
|
||||||
} from "@bitwarden/common/billing/abstractions";
|
} from "@bitwarden/common/billing/abstractions";
|
||||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||||
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
|
import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service";
|
||||||
import { BillingApiService } from "@bitwarden/common/billing/services/billing-api.service";
|
import { BillingApiService } from "@bitwarden/common/billing/services/billing-api.service";
|
||||||
import { OrganizationBillingService } from "@bitwarden/common/billing/services/organization-billing.service";
|
import { OrganizationBillingService } from "@bitwarden/common/billing/services/organization-billing.service";
|
||||||
import { PaymentMethodWarningsService } from "@bitwarden/common/billing/services/payment-method-warnings.service";
|
|
||||||
import { BraintreeService } from "@bitwarden/common/billing/services/payment-processors/braintree.service";
|
import { BraintreeService } from "@bitwarden/common/billing/services/payment-processors/braintree.service";
|
||||||
import { StripeService } from "@bitwarden/common/billing/services/payment-processors/stripe.service";
|
import { StripeService } from "@bitwarden/common/billing/services/payment-processors/stripe.service";
|
||||||
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service";
|
||||||
@ -1201,11 +1199,6 @@ const safeProviders: SafeProvider[] = [
|
|||||||
useClass: BillingApiService,
|
useClass: BillingApiService,
|
||||||
deps: [ApiServiceAbstraction, LogService, ToastService],
|
deps: [ApiServiceAbstraction, LogService, ToastService],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
|
||||||
provide: PaymentMethodWarningsServiceAbstraction,
|
|
||||||
useClass: PaymentMethodWarningsService,
|
|
||||||
deps: [BillingApiServiceAbstraction, StateProvider],
|
|
||||||
}),
|
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: BillingAccountProfileStateService,
|
provide: BillingAccountProfileStateService,
|
||||||
useClass: DefaultBillingAccountProfileStateService,
|
useClass: DefaultBillingAccountProfileStateService,
|
||||||
|
@ -8,7 +8,6 @@ import { PaymentInformationResponse } from "@bitwarden/common/billing/models/res
|
|||||||
|
|
||||||
import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request";
|
import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request";
|
||||||
import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response";
|
import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response";
|
||||||
import { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response";
|
|
||||||
import { PlanResponse } from "../../billing/models/response/plan.response";
|
import { PlanResponse } from "../../billing/models/response/plan.response";
|
||||||
import { ListResponse } from "../../models/response/list.response";
|
import { ListResponse } from "../../models/response/list.response";
|
||||||
import { CreateClientOrganizationRequest } from "../models/request/create-client-organization.request";
|
import { CreateClientOrganizationRequest } from "../models/request/create-client-organization.request";
|
||||||
@ -34,8 +33,6 @@ export abstract class BillingApiServiceAbstraction {
|
|||||||
organizationId: string,
|
organizationId: string,
|
||||||
) => Promise<OrganizationBillingMetadataResponse>;
|
) => Promise<OrganizationBillingMetadataResponse>;
|
||||||
|
|
||||||
getOrganizationBillingStatus: (id: string) => Promise<OrganizationBillingStatusResponse>;
|
|
||||||
|
|
||||||
getPlans: () => Promise<ListResponse<PlanResponse>>;
|
getPlans: () => Promise<ListResponse<PlanResponse>>;
|
||||||
|
|
||||||
getProviderClientInvoiceReport: (providerId: string, invoiceId: string) => Promise<string>;
|
getProviderClientInvoiceReport: (providerId: string, invoiceId: string) => Promise<string>;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
export * from "./account/billing-account-profile-state.service";
|
export * from "./account/billing-account-profile-state.service";
|
||||||
export * from "./billilng-api.service.abstraction";
|
export * from "./billilng-api.service.abstraction";
|
||||||
export * from "./organization-billing.service";
|
export * from "./organization-billing.service";
|
||||||
export * from "./payment-method-warnings-service.abstraction";
|
|
||||||
export * from "./payment-processors/braintree.service.abstraction";
|
export * from "./payment-processors/braintree.service.abstraction";
|
||||||
export * from "./payment-processors/stripe.service.abstraction";
|
export * from "./payment-processors/stripe.service.abstraction";
|
||||||
export * from "./provider-billing.service.abstraction";
|
export * from "./provider-billing.service.abstraction";
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
import { Observable } from "rxjs";
|
|
||||||
|
|
||||||
import { PaymentMethodWarning } from "../models/domain/payment-method-warning";
|
|
||||||
|
|
||||||
export abstract class PaymentMethodWarningsServiceAbstraction {
|
|
||||||
/**
|
|
||||||
* An {@link Observable} record in the {@link ActiveUserState} of the user's organization IDs each mapped to their respective {@link PaymentMethodWarning}.
|
|
||||||
*/
|
|
||||||
paymentMethodWarnings$: Observable<Record<string, PaymentMethodWarning>>;
|
|
||||||
/**
|
|
||||||
* Updates the {@link ActiveUserState} by setting `acknowledged` to `true` for the {@link PaymentMethodWarning} represented by the provided organization ID.
|
|
||||||
* @param organizationId - The ID of the organization whose warning you'd like to acknowledge.
|
|
||||||
*/
|
|
||||||
acknowledge: (organizationId: string) => Promise<void>;
|
|
||||||
/**
|
|
||||||
* Updates the {@link ActiveUserState} by setting `risksSubscriptionFailure` to `false` for the {@link PaymentMethodWarning} represented by the provided organization ID.
|
|
||||||
* @param organizationId - The ID of the organization whose subscription risk you'd like to remove.
|
|
||||||
*/
|
|
||||||
removeSubscriptionRisk: (organizationId: string) => Promise<void>;
|
|
||||||
/**
|
|
||||||
* Clears the {@link PaymentMethodWarning} record from the {@link ActiveUserState}.
|
|
||||||
*/
|
|
||||||
clear: () => Promise<void>;
|
|
||||||
/**
|
|
||||||
* Tries to retrieve the {@link PaymentMethodWarning} for the provided organization ID from the {@link ActiveUserState}.
|
|
||||||
* If the warning does not exist, or if the warning has been in state for longer than a week, fetches the current {@link OrganizationBillingStatusResponse} for the organization
|
|
||||||
* from the API and uses it to update the warning in state.
|
|
||||||
* @param organizationId - The ID of the organization whose {@link PaymentMethodWarning} you'd like to update.
|
|
||||||
*/
|
|
||||||
update: (organizationId: string) => Promise<void>;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import { BILLING_DISK, UserKeyDefinition } from "../../platform/state";
|
|
||||||
import { PaymentMethodWarning } from "../models/domain/payment-method-warning";
|
|
||||||
|
|
||||||
export const PAYMENT_METHOD_WARNINGS_KEY = UserKeyDefinition.record<PaymentMethodWarning>(
|
|
||||||
BILLING_DISK,
|
|
||||||
"paymentMethodWarnings",
|
|
||||||
{
|
|
||||||
deserializer: (warnings) => ({
|
|
||||||
...warnings,
|
|
||||||
savedAt: new Date(warnings.savedAt),
|
|
||||||
}),
|
|
||||||
clearOn: ["logout"],
|
|
||||||
},
|
|
||||||
);
|
|
@ -1,5 +1,4 @@
|
|||||||
export * from "./bank-account";
|
export * from "./bank-account";
|
||||||
export * from "./masked-payment-method";
|
export * from "./masked-payment-method";
|
||||||
export * from "./payment-method-warning";
|
|
||||||
export * from "./tax-information";
|
export * from "./tax-information";
|
||||||
export * from "./tokenized-payment-method";
|
export * from "./tokenized-payment-method";
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
export type PaymentMethodWarning = {
|
|
||||||
organizationName: string;
|
|
||||||
risksSubscriptionFailure: boolean;
|
|
||||||
acknowledged: boolean;
|
|
||||||
savedAt: Date;
|
|
||||||
};
|
|
@ -1,15 +0,0 @@
|
|||||||
import { BaseResponse } from "../../../models/response/base.response";
|
|
||||||
|
|
||||||
export class OrganizationBillingStatusResponse extends BaseResponse {
|
|
||||||
organizationId: string;
|
|
||||||
organizationName: string;
|
|
||||||
risksSubscriptionFailure: boolean;
|
|
||||||
|
|
||||||
constructor(response: any) {
|
|
||||||
super(response);
|
|
||||||
|
|
||||||
this.organizationId = this.getResponseProperty("OrganizationId");
|
|
||||||
this.organizationName = this.getResponseProperty("OrganizationName");
|
|
||||||
this.risksSubscriptionFailure = this.getResponseProperty("RisksSubscriptionFailure");
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,7 +12,6 @@ import { SubscriptionCancellationRequest } from "../../billing/models/request/su
|
|||||||
import { TokenizedPaymentMethodRequest } from "../../billing/models/request/tokenized-payment-method.request";
|
import { TokenizedPaymentMethodRequest } from "../../billing/models/request/tokenized-payment-method.request";
|
||||||
import { VerifyBankAccountRequest } from "../../billing/models/request/verify-bank-account.request";
|
import { VerifyBankAccountRequest } from "../../billing/models/request/verify-bank-account.request";
|
||||||
import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response";
|
import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response";
|
||||||
import { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response";
|
|
||||||
import { PaymentInformationResponse } from "../../billing/models/response/payment-information.response";
|
import { PaymentInformationResponse } from "../../billing/models/response/payment-information.response";
|
||||||
import { PlanResponse } from "../../billing/models/response/plan.response";
|
import { PlanResponse } from "../../billing/models/response/plan.response";
|
||||||
import { ListResponse } from "../../models/response/list.response";
|
import { ListResponse } from "../../models/response/list.response";
|
||||||
@ -72,17 +71,6 @@ export class BillingApiService implements BillingApiServiceAbstraction {
|
|||||||
return response as string;
|
return response as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOrganizationBillingStatus(id: string): Promise<OrganizationBillingStatusResponse> {
|
|
||||||
const r = await this.apiService.send(
|
|
||||||
"GET",
|
|
||||||
"/organizations/" + id + "/billing-status",
|
|
||||||
null,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
return new OrganizationBillingStatusResponse(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getOrganizationBillingMetadata(
|
async getOrganizationBillingMetadata(
|
||||||
organizationId: string,
|
organizationId: string,
|
||||||
): Promise<OrganizationBillingMetadataResponse> {
|
): Promise<OrganizationBillingMetadataResponse> {
|
||||||
|
@ -1,186 +0,0 @@
|
|||||||
import { any, mock, MockProxy } from "jest-mock-extended";
|
|
||||||
import { firstValueFrom } from "rxjs";
|
|
||||||
|
|
||||||
import { FakeAccountService, FakeStateProvider, mockAccountServiceWith } from "../../../spec";
|
|
||||||
import { FakeActiveUserState } from "../../../spec/fake-state";
|
|
||||||
import { Utils } from "../../platform/misc/utils";
|
|
||||||
import { UserId } from "../../types/guid";
|
|
||||||
import { BillingApiServiceAbstraction as BillingApiService } from "../abstractions/billilng-api.service.abstraction";
|
|
||||||
import { PAYMENT_METHOD_WARNINGS_KEY } from "../models/billing-keys.state";
|
|
||||||
import { PaymentMethodWarning } from "../models/domain/payment-method-warning";
|
|
||||||
import { OrganizationBillingStatusResponse } from "../models/response/organization-billing-status.response";
|
|
||||||
|
|
||||||
import { PaymentMethodWarningsService } from "./payment-method-warnings.service";
|
|
||||||
|
|
||||||
describe("Payment Method Warnings Service", () => {
|
|
||||||
let paymentMethodWarningsService: PaymentMethodWarningsService;
|
|
||||||
let billingApiService: MockProxy<BillingApiService>;
|
|
||||||
|
|
||||||
const mockUserId = Utils.newGuid() as UserId;
|
|
||||||
let accountService: FakeAccountService;
|
|
||||||
let stateProvider: FakeStateProvider;
|
|
||||||
let activeUserState: FakeActiveUserState<Record<string, PaymentMethodWarning>>;
|
|
||||||
|
|
||||||
function getPastDate(daysAgo: number) {
|
|
||||||
const date = new Date();
|
|
||||||
date.setDate(date.getDate() - daysAgo);
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getBillingStatusResponse = (organizationId: string) =>
|
|
||||||
new OrganizationBillingStatusResponse({
|
|
||||||
OrganizationId: organizationId,
|
|
||||||
OrganizationName: "Teams Organization",
|
|
||||||
RisksSubscriptionFailure: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
accountService = mockAccountServiceWith(mockUserId);
|
|
||||||
stateProvider = new FakeStateProvider(accountService);
|
|
||||||
activeUserState = stateProvider.activeUser.getFake(PAYMENT_METHOD_WARNINGS_KEY);
|
|
||||||
|
|
||||||
billingApiService = mock<BillingApiService>();
|
|
||||||
paymentMethodWarningsService = new PaymentMethodWarningsService(
|
|
||||||
billingApiService,
|
|
||||||
stateProvider,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("acknowledge", async () => {
|
|
||||||
const organizationId = "1";
|
|
||||||
const state: Record<string, PaymentMethodWarning> = {
|
|
||||||
[organizationId]: {
|
|
||||||
organizationName: "Teams Organization",
|
|
||||||
risksSubscriptionFailure: true,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: getPastDate(3),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
activeUserState.nextState(state);
|
|
||||||
await paymentMethodWarningsService.acknowledge(organizationId);
|
|
||||||
expect(await firstValueFrom(paymentMethodWarningsService.paymentMethodWarnings$)).toEqual({
|
|
||||||
[organizationId]: {
|
|
||||||
...state[organizationId],
|
|
||||||
acknowledged: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("clear", async () => {
|
|
||||||
const state: Record<string, PaymentMethodWarning> = {
|
|
||||||
"1": {
|
|
||||||
organizationName: "Teams Organization",
|
|
||||||
risksSubscriptionFailure: true,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: getPastDate(3),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
activeUserState.nextState(state);
|
|
||||||
await paymentMethodWarningsService.clear();
|
|
||||||
expect(await firstValueFrom(paymentMethodWarningsService.paymentMethodWarnings$)).toEqual({});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("removeSubscriptionRisk", async () => {
|
|
||||||
const organizationId = "1";
|
|
||||||
const state: Record<string, PaymentMethodWarning> = {
|
|
||||||
[organizationId]: {
|
|
||||||
organizationName: "Teams Organization",
|
|
||||||
risksSubscriptionFailure: true,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: getPastDate(3),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
activeUserState.nextState(state);
|
|
||||||
await paymentMethodWarningsService.removeSubscriptionRisk(organizationId);
|
|
||||||
expect(await firstValueFrom(paymentMethodWarningsService.paymentMethodWarnings$)).toEqual({
|
|
||||||
[organizationId]: {
|
|
||||||
...state[organizationId],
|
|
||||||
risksSubscriptionFailure: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("update", () => {
|
|
||||||
it("Does nothing if the stored payment method warning is less than a week old", async () => {
|
|
||||||
const organizationId = "1";
|
|
||||||
const state: Record<string, PaymentMethodWarning> = {
|
|
||||||
[organizationId]: {
|
|
||||||
organizationName: "Teams Organization",
|
|
||||||
risksSubscriptionFailure: true,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: getPastDate(3),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
activeUserState.nextState(state);
|
|
||||||
await paymentMethodWarningsService.update(organizationId);
|
|
||||||
expect(billingApiService.getOrganizationBillingStatus).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Retrieves the billing status from the API and uses it to update the state if the state is null", async () => {
|
|
||||||
const organizationId = "1";
|
|
||||||
activeUserState.nextState(null);
|
|
||||||
billingApiService.getOrganizationBillingStatus.mockResolvedValue(
|
|
||||||
getBillingStatusResponse(organizationId),
|
|
||||||
);
|
|
||||||
await paymentMethodWarningsService.update(organizationId);
|
|
||||||
expect(await firstValueFrom(paymentMethodWarningsService.paymentMethodWarnings$)).toEqual({
|
|
||||||
[organizationId]: {
|
|
||||||
organizationName: "Teams Organization",
|
|
||||||
risksSubscriptionFailure: true,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: any(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(billingApiService.getOrganizationBillingStatus).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Retrieves the billing status from the API and uses it to update the state if the stored warning is null", async () => {
|
|
||||||
const organizationId = "1";
|
|
||||||
activeUserState.nextState({
|
|
||||||
[organizationId]: null,
|
|
||||||
});
|
|
||||||
billingApiService.getOrganizationBillingStatus.mockResolvedValue(
|
|
||||||
getBillingStatusResponse(organizationId),
|
|
||||||
);
|
|
||||||
await paymentMethodWarningsService.update(organizationId);
|
|
||||||
expect(await firstValueFrom(paymentMethodWarningsService.paymentMethodWarnings$)).toEqual({
|
|
||||||
[organizationId]: {
|
|
||||||
organizationName: "Teams Organization",
|
|
||||||
risksSubscriptionFailure: true,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: any(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(billingApiService.getOrganizationBillingStatus).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Retrieves the billing status from the API and uses it to update the state if the stored warning is older than a week", async () => {
|
|
||||||
const organizationId = "1";
|
|
||||||
activeUserState.nextState({
|
|
||||||
[organizationId]: {
|
|
||||||
organizationName: "Teams Organization",
|
|
||||||
risksSubscriptionFailure: false,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: getPastDate(10),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
billingApiService.getOrganizationBillingStatus.mockResolvedValue(
|
|
||||||
new OrganizationBillingStatusResponse({
|
|
||||||
OrganizationId: organizationId,
|
|
||||||
OrganizationName: "Teams Organization",
|
|
||||||
RisksSubscriptionFailure: true,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
await paymentMethodWarningsService.update(organizationId);
|
|
||||||
expect(await firstValueFrom(paymentMethodWarningsService.paymentMethodWarnings$)).toEqual({
|
|
||||||
[organizationId]: {
|
|
||||||
organizationName: "Teams Organization",
|
|
||||||
risksSubscriptionFailure: true,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: any(),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(billingApiService.getOrganizationBillingStatus).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,74 +0,0 @@
|
|||||||
import { firstValueFrom, map, Observable } from "rxjs";
|
|
||||||
|
|
||||||
import { ActiveUserState, StateProvider } from "../../platform/state";
|
|
||||||
import { BillingApiServiceAbstraction as BillingApiService } from "../abstractions/billilng-api.service.abstraction";
|
|
||||||
import { PaymentMethodWarningsServiceAbstraction } from "../abstractions/payment-method-warnings-service.abstraction";
|
|
||||||
import { PAYMENT_METHOD_WARNINGS_KEY } from "../models/billing-keys.state";
|
|
||||||
import { PaymentMethodWarning } from "../models/domain/payment-method-warning";
|
|
||||||
|
|
||||||
export class PaymentMethodWarningsService implements PaymentMethodWarningsServiceAbstraction {
|
|
||||||
private paymentMethodWarningsState: ActiveUserState<Record<string, PaymentMethodWarning>>;
|
|
||||||
paymentMethodWarnings$: Observable<Record<string, PaymentMethodWarning>>;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private billingApiService: BillingApiService,
|
|
||||||
private stateProvider: StateProvider,
|
|
||||||
) {
|
|
||||||
this.paymentMethodWarningsState = this.stateProvider.getActive(PAYMENT_METHOD_WARNINGS_KEY);
|
|
||||||
this.paymentMethodWarnings$ = this.paymentMethodWarningsState.state$;
|
|
||||||
}
|
|
||||||
|
|
||||||
async acknowledge(organizationId: string): Promise<void> {
|
|
||||||
await this.paymentMethodWarningsState.update((state) => {
|
|
||||||
const current = state[organizationId];
|
|
||||||
state[organizationId] = {
|
|
||||||
...current,
|
|
||||||
acknowledged: true,
|
|
||||||
};
|
|
||||||
return state;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async removeSubscriptionRisk(organizationId: string): Promise<void> {
|
|
||||||
await this.paymentMethodWarningsState.update((state) => {
|
|
||||||
const current = state[organizationId];
|
|
||||||
state[organizationId] = {
|
|
||||||
...current,
|
|
||||||
risksSubscriptionFailure: false,
|
|
||||||
};
|
|
||||||
return state;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async clear(): Promise<void> {
|
|
||||||
await this.paymentMethodWarningsState.update(() => ({}));
|
|
||||||
}
|
|
||||||
|
|
||||||
async update(organizationId: string): Promise<void> {
|
|
||||||
const warning = await firstValueFrom(
|
|
||||||
this.paymentMethodWarningsState.state$.pipe(
|
|
||||||
map((state) => (!state ? null : state[organizationId])),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (!warning || warning.savedAt < this.getOneWeekAgo()) {
|
|
||||||
const { organizationName, risksSubscriptionFailure } =
|
|
||||||
await this.billingApiService.getOrganizationBillingStatus(organizationId);
|
|
||||||
await this.paymentMethodWarningsState.update((state) => {
|
|
||||||
state ??= {};
|
|
||||||
state[organizationId] = {
|
|
||||||
organizationName,
|
|
||||||
risksSubscriptionFailure,
|
|
||||||
acknowledged: false,
|
|
||||||
savedAt: new Date(),
|
|
||||||
};
|
|
||||||
return state;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getOneWeekAgo = (): Date => {
|
|
||||||
const date = new Date();
|
|
||||||
date.setDate(date.getDate() - 7);
|
|
||||||
return date;
|
|
||||||
};
|
|
||||||
}
|
|
@ -7,7 +7,6 @@ export enum FeatureFlag {
|
|||||||
BrowserFilelessImport = "browser-fileless-import",
|
BrowserFilelessImport = "browser-fileless-import",
|
||||||
ItemShare = "item-share",
|
ItemShare = "item-share",
|
||||||
GeneratorToolsModernization = "generator-tools-modernization",
|
GeneratorToolsModernization = "generator-tools-modernization",
|
||||||
ShowPaymentMethodWarningBanners = "show-payment-method-warning-banners",
|
|
||||||
EnableConsolidatedBilling = "enable-consolidated-billing",
|
EnableConsolidatedBilling = "enable-consolidated-billing",
|
||||||
AC1795_UpdatedSubscriptionStatusSection = "AC-1795_updated-subscription-status-section",
|
AC1795_UpdatedSubscriptionStatusSection = "AC-1795_updated-subscription-status-section",
|
||||||
EnableDeleteProvider = "AC-1218-delete-provider",
|
EnableDeleteProvider = "AC-1218-delete-provider",
|
||||||
@ -50,7 +49,6 @@ export const DefaultFeatureFlagValue = {
|
|||||||
[FeatureFlag.BrowserFilelessImport]: FALSE,
|
[FeatureFlag.BrowserFilelessImport]: FALSE,
|
||||||
[FeatureFlag.ItemShare]: FALSE,
|
[FeatureFlag.ItemShare]: FALSE,
|
||||||
[FeatureFlag.GeneratorToolsModernization]: FALSE,
|
[FeatureFlag.GeneratorToolsModernization]: FALSE,
|
||||||
[FeatureFlag.ShowPaymentMethodWarningBanners]: FALSE,
|
|
||||||
[FeatureFlag.EnableConsolidatedBilling]: FALSE,
|
[FeatureFlag.EnableConsolidatedBilling]: FALSE,
|
||||||
[FeatureFlag.AC1795_UpdatedSubscriptionStatusSection]: FALSE,
|
[FeatureFlag.AC1795_UpdatedSubscriptionStatusSection]: FALSE,
|
||||||
[FeatureFlag.EnableDeleteProvider]: FALSE,
|
[FeatureFlag.EnableDeleteProvider]: FALSE,
|
||||||
|
Loading…
Reference in New Issue
Block a user