mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 14:23:32 +00:00
Update client side error handling and remove add account credit from sub (#10214)
This commit is contained in:
@@ -71,7 +71,7 @@ export class WebProviderService {
|
|||||||
request.keyPair = new OrganizationKeysRequest(publicKey, encryptedPrivateKey.encryptedString);
|
request.keyPair = new OrganizationKeysRequest(publicKey, encryptedPrivateKey.encryptedString);
|
||||||
request.collectionName = encryptedCollectionName.encryptedString;
|
request.collectionName = encryptedCollectionName.encryptedString;
|
||||||
|
|
||||||
await this.billingApiService.createClientOrganization(providerId, request);
|
await this.billingApiService.createProviderClientOrganization(providerId, request);
|
||||||
|
|
||||||
await this.apiService.refreshIdentityToken();
|
await this.apiService.refreshIdentityToken();
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { DatePipe } from "@angular/common";
|
import { DatePipe } from "@angular/common";
|
||||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute } from "@angular/router";
|
||||||
import { map, Subject, takeUntil } from "rxjs";
|
import { map } from "rxjs";
|
||||||
|
|
||||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
||||||
import { InvoiceResponse } from "@bitwarden/common/billing/models/response/invoices.response";
|
import { InvoiceResponse } from "@bitwarden/common/billing/models/response/invoices.response";
|
||||||
@@ -9,16 +10,23 @@ import { InvoiceResponse } from "@bitwarden/common/billing/models/response/invoi
|
|||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./provider-billing-history.component.html",
|
templateUrl: "./provider-billing-history.component.html",
|
||||||
})
|
})
|
||||||
export class ProviderBillingHistoryComponent implements OnInit, OnDestroy {
|
export class ProviderBillingHistoryComponent {
|
||||||
private providerId: string;
|
private providerId: string;
|
||||||
|
|
||||||
private destroy$ = new Subject<void>();
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private billingApiService: BillingApiServiceAbstraction,
|
private billingApiService: BillingApiServiceAbstraction,
|
||||||
private datePipe: DatePipe,
|
private datePipe: DatePipe,
|
||||||
) {}
|
) {
|
||||||
|
this.activatedRoute.params
|
||||||
|
.pipe(
|
||||||
|
map(({ providerId }) => {
|
||||||
|
this.providerId = providerId;
|
||||||
|
}),
|
||||||
|
takeUntilDestroyed(),
|
||||||
|
)
|
||||||
|
.subscribe();
|
||||||
|
}
|
||||||
|
|
||||||
getClientInvoiceReport = (invoiceId: string) =>
|
getClientInvoiceReport = (invoiceId: string) =>
|
||||||
this.billingApiService.getProviderClientInvoiceReport(this.providerId, invoiceId);
|
this.billingApiService.getProviderClientInvoiceReport(this.providerId, invoiceId);
|
||||||
@@ -29,20 +37,4 @@ export class ProviderBillingHistoryComponent implements OnInit, OnDestroy {
|
|||||||
};
|
};
|
||||||
|
|
||||||
getInvoices = async () => await this.billingApiService.getProviderInvoices(this.providerId);
|
getInvoices = async () => await this.billingApiService.getProviderInvoices(this.providerId);
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.activatedRoute.params
|
|
||||||
.pipe(
|
|
||||||
map(({ providerId }) => {
|
|
||||||
this.providerId = providerId;
|
|
||||||
}),
|
|
||||||
takeUntil(this.destroy$),
|
|
||||||
)
|
|
||||||
.subscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.destroy$.next();
|
|
||||||
this.destroy$.complete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export class ManageClientNameDialogComponent {
|
|||||||
request.assignedSeats = this.dialogParams.organization.seats;
|
request.assignedSeats = this.dialogParams.organization.seats;
|
||||||
request.name = this.formGroup.value.name;
|
request.name = this.formGroup.value.name;
|
||||||
|
|
||||||
await this.billingApiService.updateClientOrganization(
|
await this.billingApiService.updateProviderClientOrganization(
|
||||||
this.dialogParams.providerId,
|
this.dialogParams.providerId,
|
||||||
this.dialogParams.organization.id,
|
this.dialogParams.organization.id,
|
||||||
request,
|
request,
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export class ManageClientSubscriptionDialogComponent implements OnInit {
|
|||||||
request.assignedSeats = this.formGroup.value.assignedSeats;
|
request.assignedSeats = this.formGroup.value.assignedSeats;
|
||||||
request.name = this.dialogParams.organization.organizationName;
|
request.name = this.dialogParams.organization.organizationName;
|
||||||
|
|
||||||
await this.billingApiService.updateClientOrganization(
|
await this.billingApiService.updateProviderClientOrganization(
|
||||||
this.dialogParams.provider.id,
|
this.dialogParams.provider.id,
|
||||||
this.dialogParams.organization.id,
|
this.dialogParams.organization.id,
|
||||||
request,
|
request,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
import { ActivatedRoute, Router } from "@angular/router";
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { firstValueFrom, from, lastValueFrom, map } from "rxjs";
|
import { firstValueFrom, from, lastValueFrom, map } from "rxjs";
|
||||||
import { switchMap, takeUntil } from "rxjs/operators";
|
import { switchMap } from "rxjs/operators";
|
||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
|
||||||
import { SearchService } from "@bitwarden/common/abstractions/search.service";
|
import { SearchService } from "@bitwarden/common/abstractions/search.service";
|
||||||
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||||
import { ProviderUserType } from "@bitwarden/common/admin-console/enums";
|
import { ProviderUserType } from "@bitwarden/common/admin-console/enums";
|
||||||
@@ -46,7 +46,6 @@ export class ManageClientsComponent extends BaseClientsComponent {
|
|||||||
protected plans: PlanResponse[];
|
protected plans: PlanResponse[];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private apiService: ApiService,
|
|
||||||
private billingApiService: BillingApiService,
|
private billingApiService: BillingApiService,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private providerService: ProviderService,
|
private providerService: ProviderService,
|
||||||
@@ -68,9 +67,7 @@ export class ManageClientsComponent extends BaseClientsComponent {
|
|||||||
validationService,
|
validationService,
|
||||||
webProviderService,
|
webProviderService,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.activatedRoute.parent.params
|
this.activatedRoute.parent.params
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap((params) => {
|
switchMap((params) => {
|
||||||
@@ -90,15 +87,11 @@ export class ManageClientsComponent extends BaseClientsComponent {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
takeUntil(this.destroy$),
|
takeUntilDestroyed(),
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
super.ngOnDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
removeMonthly = (plan: string) => plan.replace(" (Monthly)", "");
|
removeMonthly = (plan: string) => plan.replace(" (Monthly)", "");
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
@@ -106,7 +99,9 @@ export class ManageClientsComponent extends BaseClientsComponent {
|
|||||||
|
|
||||||
this.isProviderAdmin = this.provider.type === ProviderUserType.ProviderAdmin;
|
this.isProviderAdmin = this.provider.type === ProviderUserType.ProviderAdmin;
|
||||||
|
|
||||||
this.clients = (await this.apiService.getProviderClients(this.providerId)).data;
|
this.clients = (
|
||||||
|
await this.billingApiService.getProviderClientOrganizations(this.providerId)
|
||||||
|
).data;
|
||||||
|
|
||||||
this.dataSource.data = this.clients;
|
this.dataSource.data = this.clients;
|
||||||
|
|
||||||
|
|||||||
@@ -69,9 +69,6 @@
|
|||||||
</h2>
|
</h2>
|
||||||
<p class="tw-text-lg tw-font-bold">{{ subscription.accountCredit | currency: "$" }}</p>
|
<p class="tw-text-lg tw-font-bold">{{ subscription.accountCredit | currency: "$" }}</p>
|
||||||
<p bitTypography="body1">{{ "creditAppliedDesc" | i18n }}</p>
|
<p bitTypography="body1">{{ "creditAppliedDesc" | i18n }}</p>
|
||||||
<button type="button" bitButton buttonType="secondary" [bitAction]="addAccountCredit">
|
|
||||||
{{ "addCredit" | i18n }}
|
|
||||||
</button>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<!-- Tax Information -->
|
<!-- Tax Information -->
|
||||||
<ng-container>
|
<ng-container>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { Component } from "@angular/core";
|
|||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute } from "@angular/router";
|
||||||
import { Subject, concatMap, takeUntil } from "rxjs";
|
import { Subject, concatMap, takeUntil } from "rxjs";
|
||||||
|
|
||||||
import { openAddAccountCreditDialog } from "@bitwarden/angular/billing/components";
|
|
||||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction";
|
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction";
|
||||||
import { TaxInformation } from "@bitwarden/common/billing/models/domain";
|
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";
|
||||||
@@ -11,7 +10,7 @@ import {
|
|||||||
ProviderSubscriptionResponse,
|
ProviderSubscriptionResponse,
|
||||||
} from "@bitwarden/common/billing/models/response/provider-subscription-response";
|
} from "@bitwarden/common/billing/models/response/provider-subscription-response";
|
||||||
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 { ToastService } from "@bitwarden/components";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-provider-subscription",
|
selector: "app-provider-subscription",
|
||||||
@@ -27,9 +26,10 @@ export class ProviderSubscriptionComponent {
|
|||||||
totalCost: number;
|
totalCost: number;
|
||||||
currentDate = new Date();
|
currentDate = new Date();
|
||||||
|
|
||||||
|
protected readonly TaxInformation = TaxInformation;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private billingApiService: BillingApiServiceAbstraction,
|
private billingApiService: BillingApiServiceAbstraction,
|
||||||
private dialogService: DialogService,
|
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
@@ -63,13 +63,6 @@ export class ProviderSubscriptionComponent {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
addAccountCredit = () =>
|
|
||||||
openAddAccountCreditDialog(this.dialogService, {
|
|
||||||
data: {
|
|
||||||
providerId: this.providerId,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
updateTaxInformation = async (taxInformation: TaxInformation) => {
|
updateTaxInformation = async (taxInformation: TaxInformation) => {
|
||||||
const request = ExpandedTaxInfoUpdateRequest.From(taxInformation);
|
const request = ExpandedTaxInfoUpdateRequest.From(taxInformation);
|
||||||
await this.billingApiService.updateProviderTaxInformation(this.providerId, request);
|
await this.billingApiService.updateProviderTaxInformation(this.providerId, request);
|
||||||
@@ -108,6 +101,4 @@ export class ProviderSubscriptionComponent {
|
|||||||
this.destroy$.next();
|
this.destroy$.next();
|
||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected readonly TaxInformation = TaxInformation;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1196,7 +1196,7 @@ const safeProviders: SafeProvider[] = [
|
|||||||
safeProvider({
|
safeProvider({
|
||||||
provide: BillingApiServiceAbstraction,
|
provide: BillingApiServiceAbstraction,
|
||||||
useClass: BillingApiService,
|
useClass: BillingApiService,
|
||||||
deps: [ApiServiceAbstraction],
|
deps: [ApiServiceAbstraction, LogService, ToastService],
|
||||||
}),
|
}),
|
||||||
safeProvider({
|
safeProvider({
|
||||||
provide: PaymentMethodWarningsServiceAbstraction,
|
provide: PaymentMethodWarningsServiceAbstraction,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response";
|
||||||
import { PaymentMethodType } from "@bitwarden/common/billing/enums";
|
import { PaymentMethodType } from "@bitwarden/common/billing/enums";
|
||||||
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 { TokenizedPaymentMethodRequest } from "@bitwarden/common/billing/models/request/tokenized-payment-method.request";
|
import { TokenizedPaymentMethodRequest } from "@bitwarden/common/billing/models/request/tokenized-payment-method.request";
|
||||||
@@ -8,7 +9,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 { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response";
|
||||||
import { OrganizationSubscriptionResponse } from "../../billing/models/response/organization-subscription.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";
|
||||||
@@ -23,39 +23,45 @@ export abstract class BillingApiServiceAbstraction {
|
|||||||
|
|
||||||
cancelPremiumUserSubscription: (request: SubscriptionCancellationRequest) => Promise<void>;
|
cancelPremiumUserSubscription: (request: SubscriptionCancellationRequest) => Promise<void>;
|
||||||
|
|
||||||
createClientOrganization: (
|
createProviderClientOrganization: (
|
||||||
providerId: string,
|
providerId: string,
|
||||||
request: CreateClientOrganizationRequest,
|
request: CreateClientOrganizationRequest,
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
|
|
||||||
createSetupIntent: (paymentMethodType: PaymentMethodType) => Promise<string>;
|
createSetupIntent: (paymentMethodType: PaymentMethodType) => Promise<string>;
|
||||||
|
|
||||||
getBillingStatus: (id: string) => Promise<OrganizationBillingStatusResponse>;
|
|
||||||
|
|
||||||
getOrganizationBillingMetadata: (
|
getOrganizationBillingMetadata: (
|
||||||
organizationId: string,
|
organizationId: string,
|
||||||
) => Promise<OrganizationBillingMetadataResponse>;
|
) => Promise<OrganizationBillingMetadataResponse>;
|
||||||
|
|
||||||
getOrganizationSubscription: (
|
getOrganizationBillingStatus: (id: string) => Promise<OrganizationBillingStatusResponse>;
|
||||||
organizationId: string,
|
|
||||||
) => Promise<OrganizationSubscriptionResponse>;
|
|
||||||
|
|
||||||
getPlans: () => Promise<ListResponse<PlanResponse>>;
|
getPlans: () => Promise<ListResponse<PlanResponse>>;
|
||||||
|
|
||||||
getProviderClientInvoiceReport: (providerId: string, invoiceId: string) => Promise<string>;
|
getProviderClientInvoiceReport: (providerId: string, invoiceId: string) => Promise<string>;
|
||||||
|
|
||||||
|
getProviderClientOrganizations: (
|
||||||
|
providerId: string,
|
||||||
|
) => Promise<ListResponse<ProviderOrganizationOrganizationDetailsResponse>>;
|
||||||
|
|
||||||
getProviderInvoices: (providerId: string) => Promise<InvoicesResponse>;
|
getProviderInvoices: (providerId: string) => Promise<InvoicesResponse>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This endpoint is currently deactivated.
|
||||||
|
*/
|
||||||
getProviderPaymentInformation: (providerId: string) => Promise<PaymentInformationResponse>;
|
getProviderPaymentInformation: (providerId: string) => Promise<PaymentInformationResponse>;
|
||||||
|
|
||||||
getProviderSubscription: (providerId: string) => Promise<ProviderSubscriptionResponse>;
|
getProviderSubscription: (providerId: string) => Promise<ProviderSubscriptionResponse>;
|
||||||
|
|
||||||
updateClientOrganization: (
|
updateProviderClientOrganization: (
|
||||||
providerId: string,
|
providerId: string,
|
||||||
organizationId: string,
|
organizationId: string,
|
||||||
request: UpdateClientOrganizationRequest,
|
request: UpdateClientOrganizationRequest,
|
||||||
) => Promise<any>;
|
) => Promise<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This endpoint is currently deactivated.
|
||||||
|
*/
|
||||||
updateProviderPaymentMethod: (
|
updateProviderPaymentMethod: (
|
||||||
providerId: string,
|
providerId: string,
|
||||||
request: TokenizedPaymentMethodRequest,
|
request: TokenizedPaymentMethodRequest,
|
||||||
@@ -66,6 +72,9 @@ export abstract class BillingApiServiceAbstraction {
|
|||||||
request: ExpandedTaxInfoUpdateRequest,
|
request: ExpandedTaxInfoUpdateRequest,
|
||||||
) => Promise<void>;
|
) => Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This endpoint is currently deactivated.
|
||||||
|
*/
|
||||||
verifyProviderBankAccount: (
|
verifyProviderBankAccount: (
|
||||||
providerId: string,
|
providerId: string,
|
||||||
request: VerifyBankAccountRequest,
|
request: VerifyBankAccountRequest,
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
|
import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response";
|
||||||
import { InvoicesResponse } from "@bitwarden/common/billing/models/response/invoices.response";
|
import { InvoicesResponse } from "@bitwarden/common/billing/models/response/invoices.response";
|
||||||
|
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
|
||||||
|
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||||
|
import { ToastService } from "@bitwarden/components";
|
||||||
|
|
||||||
import { ApiService } from "../../abstractions/api.service";
|
import { ApiService } from "../../abstractions/api.service";
|
||||||
import { BillingApiServiceAbstraction } from "../../billing/abstractions";
|
import { BillingApiServiceAbstraction } from "../../billing/abstractions";
|
||||||
@@ -9,7 +13,6 @@ import { TokenizedPaymentMethodRequest } from "../../billing/models/request/toke
|
|||||||
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 { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response";
|
||||||
import { OrganizationSubscriptionResponse } from "../../billing/models/response/organization-subscription.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";
|
||||||
@@ -18,7 +21,11 @@ import { UpdateClientOrganizationRequest } from "../models/request/update-client
|
|||||||
import { ProviderSubscriptionResponse } from "../models/response/provider-subscription-response";
|
import { ProviderSubscriptionResponse } from "../models/response/provider-subscription-response";
|
||||||
|
|
||||||
export class BillingApiService implements BillingApiServiceAbstraction {
|
export class BillingApiService implements BillingApiServiceAbstraction {
|
||||||
constructor(private apiService: ApiService) {}
|
constructor(
|
||||||
|
private apiService: ApiService,
|
||||||
|
private logService: LogService,
|
||||||
|
private toastService: ToastService,
|
||||||
|
) {}
|
||||||
|
|
||||||
cancelOrganizationSubscription(
|
cancelOrganizationSubscription(
|
||||||
organizationId: string,
|
organizationId: string,
|
||||||
@@ -37,7 +44,7 @@ export class BillingApiService implements BillingApiServiceAbstraction {
|
|||||||
return this.apiService.send("POST", "/accounts/cancel", request, true, false);
|
return this.apiService.send("POST", "/accounts/cancel", request, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
createClientOrganization(
|
createProviderClientOrganization(
|
||||||
providerId: string,
|
providerId: string,
|
||||||
request: CreateClientOrganizationRequest,
|
request: CreateClientOrganizationRequest,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@@ -65,7 +72,7 @@ export class BillingApiService implements BillingApiServiceAbstraction {
|
|||||||
return response as string;
|
return response as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBillingStatus(id: string): Promise<OrganizationBillingStatusResponse> {
|
async getOrganizationBillingStatus(id: string): Promise<OrganizationBillingStatusResponse> {
|
||||||
const r = await this.apiService.send(
|
const r = await this.apiService.send(
|
||||||
"GET",
|
"GET",
|
||||||
"/organizations/" + id + "/billing-status",
|
"/organizations/" + id + "/billing-status",
|
||||||
@@ -90,19 +97,6 @@ export class BillingApiService implements BillingApiServiceAbstraction {
|
|||||||
return new OrganizationBillingMetadataResponse(r);
|
return new OrganizationBillingMetadataResponse(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOrganizationSubscription(
|
|
||||||
organizationId: string,
|
|
||||||
): Promise<OrganizationSubscriptionResponse> {
|
|
||||||
const r = await this.apiService.send(
|
|
||||||
"GET",
|
|
||||||
"/organizations/" + organizationId + "/subscription",
|
|
||||||
null,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
return new OrganizationSubscriptionResponse(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getPlans(): Promise<ListResponse<PlanResponse>> {
|
async getPlans(): Promise<ListResponse<PlanResponse>> {
|
||||||
const r = await this.apiService.send("GET", "/plans", null, false, true);
|
const r = await this.apiService.send("GET", "/plans", null, false, true);
|
||||||
return new ListResponse(r, PlanResponse);
|
return new ListResponse(r, PlanResponse);
|
||||||
@@ -119,40 +113,55 @@ export class BillingApiService implements BillingApiServiceAbstraction {
|
|||||||
return response as string;
|
return response as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getProviderClientOrganizations(
|
||||||
|
providerId: string,
|
||||||
|
): Promise<ListResponse<ProviderOrganizationOrganizationDetailsResponse>> {
|
||||||
|
const response = await this.execute(() =>
|
||||||
|
this.apiService.send("GET", "/providers/" + providerId + "/organizations", null, true, true),
|
||||||
|
);
|
||||||
|
return new ListResponse(response, ProviderOrganizationOrganizationDetailsResponse);
|
||||||
|
}
|
||||||
|
|
||||||
async getProviderInvoices(providerId: string): Promise<InvoicesResponse> {
|
async getProviderInvoices(providerId: string): Promise<InvoicesResponse> {
|
||||||
const response = await this.apiService.send(
|
const response = await this.execute(() =>
|
||||||
"GET",
|
this.apiService.send(
|
||||||
"/providers/" + providerId + "/billing/invoices",
|
"GET",
|
||||||
null,
|
"/providers/" + providerId + "/billing/invoices",
|
||||||
true,
|
null,
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return new InvoicesResponse(response);
|
return new InvoicesResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getProviderPaymentInformation(providerId: string): Promise<PaymentInformationResponse> {
|
async getProviderPaymentInformation(providerId: string): Promise<PaymentInformationResponse> {
|
||||||
const response = await this.apiService.send(
|
const response = await this.execute(() =>
|
||||||
"GET",
|
this.apiService.send(
|
||||||
"/providers/" + providerId + "/billing/payment-information",
|
"GET",
|
||||||
null,
|
"/providers/" + providerId + "/billing/payment-information",
|
||||||
true,
|
null,
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return new PaymentInformationResponse(response);
|
return new PaymentInformationResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getProviderSubscription(providerId: string): Promise<ProviderSubscriptionResponse> {
|
async getProviderSubscription(providerId: string): Promise<ProviderSubscriptionResponse> {
|
||||||
const r = await this.apiService.send(
|
const response = await this.execute(() =>
|
||||||
"GET",
|
this.apiService.send(
|
||||||
"/providers/" + providerId + "/billing/subscription",
|
"GET",
|
||||||
null,
|
"/providers/" + providerId + "/billing/subscription",
|
||||||
true,
|
null,
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return new ProviderSubscriptionResponse(r);
|
return new ProviderSubscriptionResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateClientOrganization(
|
async updateProviderClientOrganization(
|
||||||
providerId: string,
|
providerId: string,
|
||||||
organizationId: string,
|
organizationId: string,
|
||||||
request: UpdateClientOrganizationRequest,
|
request: UpdateClientOrganizationRequest,
|
||||||
@@ -198,4 +207,20 @@ export class BillingApiService implements BillingApiServiceAbstraction {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async execute(request: () => Promise<any>): Promise<any> {
|
||||||
|
try {
|
||||||
|
return await request();
|
||||||
|
} catch (error) {
|
||||||
|
this.logService.error(error);
|
||||||
|
if (error instanceof ErrorResponse) {
|
||||||
|
this.toastService.showToast({
|
||||||
|
variant: "error",
|
||||||
|
title: null,
|
||||||
|
message: error.getSingleMessage(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,13 +113,13 @@ describe("Payment Method Warnings Service", () => {
|
|||||||
};
|
};
|
||||||
activeUserState.nextState(state);
|
activeUserState.nextState(state);
|
||||||
await paymentMethodWarningsService.update(organizationId);
|
await paymentMethodWarningsService.update(organizationId);
|
||||||
expect(billingApiService.getBillingStatus).not.toHaveBeenCalled();
|
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 () => {
|
it("Retrieves the billing status from the API and uses it to update the state if the state is null", async () => {
|
||||||
const organizationId = "1";
|
const organizationId = "1";
|
||||||
activeUserState.nextState(null);
|
activeUserState.nextState(null);
|
||||||
billingApiService.getBillingStatus.mockResolvedValue(
|
billingApiService.getOrganizationBillingStatus.mockResolvedValue(
|
||||||
getBillingStatusResponse(organizationId),
|
getBillingStatusResponse(organizationId),
|
||||||
);
|
);
|
||||||
await paymentMethodWarningsService.update(organizationId);
|
await paymentMethodWarningsService.update(organizationId);
|
||||||
@@ -131,7 +131,7 @@ describe("Payment Method Warnings Service", () => {
|
|||||||
savedAt: any(),
|
savedAt: any(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(billingApiService.getBillingStatus).toHaveBeenCalledTimes(1);
|
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 () => {
|
it("Retrieves the billing status from the API and uses it to update the state if the stored warning is null", async () => {
|
||||||
@@ -139,7 +139,7 @@ describe("Payment Method Warnings Service", () => {
|
|||||||
activeUserState.nextState({
|
activeUserState.nextState({
|
||||||
[organizationId]: null,
|
[organizationId]: null,
|
||||||
});
|
});
|
||||||
billingApiService.getBillingStatus.mockResolvedValue(
|
billingApiService.getOrganizationBillingStatus.mockResolvedValue(
|
||||||
getBillingStatusResponse(organizationId),
|
getBillingStatusResponse(organizationId),
|
||||||
);
|
);
|
||||||
await paymentMethodWarningsService.update(organizationId);
|
await paymentMethodWarningsService.update(organizationId);
|
||||||
@@ -151,7 +151,7 @@ describe("Payment Method Warnings Service", () => {
|
|||||||
savedAt: any(),
|
savedAt: any(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(billingApiService.getBillingStatus).toHaveBeenCalledTimes(1);
|
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 () => {
|
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 () => {
|
||||||
@@ -164,7 +164,7 @@ describe("Payment Method Warnings Service", () => {
|
|||||||
savedAt: getPastDate(10),
|
savedAt: getPastDate(10),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
billingApiService.getBillingStatus.mockResolvedValue(
|
billingApiService.getOrganizationBillingStatus.mockResolvedValue(
|
||||||
new OrganizationBillingStatusResponse({
|
new OrganizationBillingStatusResponse({
|
||||||
OrganizationId: organizationId,
|
OrganizationId: organizationId,
|
||||||
OrganizationName: "Teams Organization",
|
OrganizationName: "Teams Organization",
|
||||||
@@ -180,7 +180,7 @@ describe("Payment Method Warnings Service", () => {
|
|||||||
savedAt: any(),
|
savedAt: any(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(billingApiService.getBillingStatus).toHaveBeenCalledTimes(1);
|
expect(billingApiService.getOrganizationBillingStatus).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export class PaymentMethodWarningsService implements PaymentMethodWarningsServic
|
|||||||
);
|
);
|
||||||
if (!warning || warning.savedAt < this.getOneWeekAgo()) {
|
if (!warning || warning.savedAt < this.getOneWeekAgo()) {
|
||||||
const { organizationName, risksSubscriptionFailure } =
|
const { organizationName, risksSubscriptionFailure } =
|
||||||
await this.billingApiService.getBillingStatus(organizationId);
|
await this.billingApiService.getOrganizationBillingStatus(organizationId);
|
||||||
await this.paymentMethodWarningsState.update((state) => {
|
await this.paymentMethodWarningsState.update((state) => {
|
||||||
state ??= {};
|
state ??= {};
|
||||||
state[organizationId] = {
|
state[organizationId] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user