1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-05 19:23:19 +00:00

fix(billing)!: rename tax-client in components

This commit is contained in:
Stephon Brown
2026-01-20 11:08:45 -05:00
parent e2413e3e65
commit e19621c751
8 changed files with 77 additions and 58 deletions

View File

@@ -15,7 +15,7 @@ import {
DialogService,
} from "@bitwarden/components";
import { AccountBillingClient, TaxClient } from "../../../clients";
import { AccountBillingClient, PreviewInvoiceClient } from "../../../clients";
import { BillingServicesModule } from "../../../services";
import { UpgradeAccountComponent } from "../upgrade-account/upgrade-account.component";
import { UpgradePaymentService } from "../upgrade-payment/services/upgrade-payment.service";
@@ -74,7 +74,7 @@ export type UnifiedUpgradeDialogParams = {
UpgradePaymentComponent,
BillingServicesModule,
],
providers: [UpgradePaymentService, AccountBillingClient, TaxClient],
providers: [UpgradePaymentService, AccountBillingClient, PreviewInvoiceClient],
templateUrl: "./unified-upgrade-dialog.component.html",
})
export class UnifiedUpgradeDialogComponent implements OnInit {

View File

@@ -21,7 +21,7 @@ import {
AccountBillingClient,
SubscriberBillingClient,
TaxAmounts,
TaxClient,
PreviewInvoiceClient,
} from "../../../../clients";
import {
BillingAddress,
@@ -35,7 +35,7 @@ import { UpgradePaymentService, PlanDetails } from "./upgrade-payment.service";
describe("UpgradePaymentService", () => {
const mockOrganizationBillingService = mock<OrganizationBillingServiceAbstraction>();
const mockAccountBillingClient = mock<AccountBillingClient>();
const mockTaxClient = mock<TaxClient>();
const mockPreviewInvoiceClient = mock<PreviewInvoiceClient>();
const mockLogService = mock<LogService>();
const mockSyncService = mock<SyncService>();
const mockOrganizationService = mock<OrganizationService>();
@@ -112,7 +112,7 @@ describe("UpgradePaymentService", () => {
beforeEach(() => {
mockReset(mockOrganizationBillingService);
mockReset(mockAccountBillingClient);
mockReset(mockTaxClient);
mockReset(mockPreviewInvoiceClient);
mockReset(mockLogService);
mockReset(mockOrganizationService);
mockReset(mockAccountService);
@@ -133,7 +133,7 @@ describe("UpgradePaymentService", () => {
useValue: mockOrganizationBillingService,
},
{ provide: AccountBillingClient, useValue: mockAccountBillingClient },
{ provide: TaxClient, useValue: mockTaxClient },
{ provide: PreviewInvoiceClient, useValue: mockPreviewInvoiceClient },
{ provide: LogService, useValue: mockLogService },
{ provide: SyncService, useValue: mockSyncService },
{ provide: OrganizationService, useValue: mockOrganizationService },
@@ -183,7 +183,7 @@ describe("UpgradePaymentService", () => {
const service = new UpgradePaymentService(
mockOrganizationBillingService,
mockAccountBillingClient,
mockTaxClient,
mockPreviewInvoiceClient,
mockLogService,
mockSyncService,
mockOrganizationService,
@@ -236,7 +236,7 @@ describe("UpgradePaymentService", () => {
const service = new UpgradePaymentService(
mockOrganizationBillingService,
mockAccountBillingClient,
mockTaxClient,
mockPreviewInvoiceClient,
mockLogService,
mockSyncService,
mockOrganizationService,
@@ -271,7 +271,7 @@ describe("UpgradePaymentService", () => {
const service = new UpgradePaymentService(
mockOrganizationBillingService,
mockAccountBillingClient,
mockTaxClient,
mockPreviewInvoiceClient,
mockLogService,
mockSyncService,
mockOrganizationService,
@@ -307,7 +307,7 @@ describe("UpgradePaymentService", () => {
const service = new UpgradePaymentService(
mockOrganizationBillingService,
mockAccountBillingClient,
mockTaxClient,
mockPreviewInvoiceClient,
mockLogService,
mockSyncService,
mockOrganizationService,
@@ -333,7 +333,7 @@ describe("UpgradePaymentService", () => {
const service = new UpgradePaymentService(
mockOrganizationBillingService,
mockAccountBillingClient,
mockTaxClient,
mockPreviewInvoiceClient,
mockLogService,
mockSyncService,
mockOrganizationService,
@@ -389,7 +389,7 @@ describe("UpgradePaymentService", () => {
const service = new UpgradePaymentService(
mockOrganizationBillingService,
mockAccountBillingClient,
mockTaxClient,
mockPreviewInvoiceClient,
mockLogService,
mockSyncService,
mockOrganizationService,
@@ -412,17 +412,18 @@ describe("UpgradePaymentService", () => {
const mockResponse = mock<TaxAmounts>();
mockResponse.tax = 2.5;
mockTaxClient.previewTaxForPremiumSubscriptionPurchase.mockResolvedValue(mockResponse);
mockPreviewInvoiceClient.previewTaxForPremiumSubscriptionPurchase.mockResolvedValue(
mockResponse,
);
// Act
const result = await sut.calculateEstimatedTax(mockPremiumPlanDetails, mockBillingAddress);
// Assert
expect(result).toEqual(2.5);
expect(mockTaxClient.previewTaxForPremiumSubscriptionPurchase).toHaveBeenCalledWith(
0,
mockBillingAddress,
);
expect(
mockPreviewInvoiceClient.previewTaxForPremiumSubscriptionPurchase,
).toHaveBeenCalledWith(0, mockBillingAddress);
});
it("should calculate tax for families plan", async () => {
@@ -430,14 +431,18 @@ describe("UpgradePaymentService", () => {
const mockResponse = mock<TaxAmounts>();
mockResponse.tax = 5.0;
mockTaxClient.previewTaxForOrganizationSubscriptionPurchase.mockResolvedValue(mockResponse);
mockPreviewInvoiceClient.previewTaxForOrganizationSubscriptionPurchase.mockResolvedValue(
mockResponse,
);
// Act
const result = await sut.calculateEstimatedTax(mockFamiliesPlanDetails, mockBillingAddress);
// Assert
expect(result).toEqual(5.0);
expect(mockTaxClient.previewTaxForOrganizationSubscriptionPurchase).toHaveBeenCalledWith(
expect(
mockPreviewInvoiceClient.previewTaxForOrganizationSubscriptionPurchase,
).toHaveBeenCalledWith(
{
cadence: "annually",
tier: "families",
@@ -454,7 +459,7 @@ describe("UpgradePaymentService", () => {
it("should throw and log error if personal tax calculation fails", async () => {
// Arrange
const error = new Error("Tax service error");
mockTaxClient.previewTaxForPremiumSubscriptionPurchase.mockRejectedValue(error);
mockPreviewInvoiceClient.previewTaxForPremiumSubscriptionPurchase.mockRejectedValue(error);
// Act & Assert
await expect(
@@ -466,7 +471,9 @@ describe("UpgradePaymentService", () => {
it("should throw and log error if organization tax calculation fails", async () => {
// Arrange
const error = new Error("Tax service error");
mockTaxClient.previewTaxForOrganizationSubscriptionPurchase.mockRejectedValue(error);
mockPreviewInvoiceClient.previewTaxForOrganizationSubscriptionPurchase.mockRejectedValue(
error,
);
// Act & Assert
await expect(
sut.calculateEstimatedTax(mockFamiliesPlanDetails, mockBillingAddress),

View File

@@ -26,7 +26,7 @@ import {
OrganizationSubscriptionPurchase,
SubscriberBillingClient,
TaxAmounts,
TaxClient,
PreviewInvoiceClient,
} from "../../../../clients";
import {
BillingAddress,
@@ -58,7 +58,7 @@ export class UpgradePaymentService {
constructor(
private organizationBillingService: OrganizationBillingServiceAbstraction,
private accountBillingClient: AccountBillingClient,
private taxClient: TaxClient,
private previewInvoiceClient: PreviewInvoiceClient,
private logService: LogService,
private syncService: SyncService,
private organizationService: OrganizationService,
@@ -101,7 +101,7 @@ export class UpgradePaymentService {
const isFamiliesPlan = planDetails.tier === PersonalSubscriptionPricingTierIds.Families;
const isPremiumPlan = planDetails.tier === PersonalSubscriptionPricingTierIds.Premium;
let taxClientCall: Promise<TaxAmounts> | null = null;
let previewInvoiceClientCall: Promise<TaxAmounts> | null = null;
if (isFamiliesPlan) {
// Currently, only Families plan is supported for organization plans
@@ -111,22 +111,26 @@ export class UpgradePaymentService {
passwordManager: { seats: 1, additionalStorage: 0, sponsored: false },
};
taxClientCall = this.taxClient.previewTaxForOrganizationSubscriptionPurchase(
request,
previewInvoiceClientCall =
this.previewInvoiceClient.previewTaxForOrganizationSubscriptionPurchase(
request,
billingAddress,
);
}
if (isPremiumPlan) {
previewInvoiceClientCall = this.previewInvoiceClient.previewTaxForPremiumSubscriptionPurchase(
0,
billingAddress,
);
}
if (isPremiumPlan) {
taxClientCall = this.taxClient.previewTaxForPremiumSubscriptionPurchase(0, billingAddress);
}
if (taxClientCall === null) {
if (previewInvoiceClientCall === null) {
throw new Error("Tax client call is not defined");
}
try {
const preview = await taxClientCall;
const preview = await previewInvoiceClientCall;
return preview.tax;
} catch (error) {
this.logService.error("Tax calculation failed:", error);

View File

@@ -50,7 +50,7 @@ import { KeyService } from "@bitwarden/key-management";
import {
OrganizationSubscriptionPlan,
SubscriberBillingClient,
TaxClient,
PreviewInvoiceClient,
} from "@bitwarden/web-vault/app/billing/clients";
import { OrganizationWarningsService } from "@bitwarden/web-vault/app/billing/organizations/warnings/services";
import {
@@ -117,7 +117,7 @@ interface OnSuccessArgs {
EnterBillingAddressComponent,
CardComponent,
],
providers: [SubscriberBillingClient, TaxClient],
providers: [SubscriberBillingClient, PreviewInvoiceClient],
})
export class ChangePlanDialogComponent implements OnInit, OnDestroy {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
@@ -248,7 +248,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
private accountService: AccountService,
private billingNotificationService: BillingNotificationService,
private subscriberBillingClient: SubscriberBillingClient,
private taxClient: TaxClient,
private previewInvoiceClient: PreviewInvoiceClient,
private organizationWarningsService: OrganizationWarningsService,
private configService: ConfigService,
) {}
@@ -1068,11 +1068,12 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
? getBillingAddressFromForm(this.billingFormGroup.controls.billingAddress)
: this.billingAddress;
const taxAmounts = await this.taxClient.previewTaxForOrganizationSubscriptionPlanChange(
this.organizationId,
getPlanFromLegacyEnum(this.selectedPlan.type),
billingAddress,
);
const taxAmounts =
await this.previewInvoiceClient.previewTaxForOrganizationSubscriptionPlanChange(
this.organizationId,
getPlanFromLegacyEnum(this.selectedPlan.type),
billingAddress,
);
this.estimatedTax = taxAmounts.tax;
}

View File

@@ -52,8 +52,8 @@ import { KeyService } from "@bitwarden/key-management";
import {
OrganizationSubscriptionPlan,
OrganizationSubscriptionPurchase,
PreviewInvoiceClient,
SubscriberBillingClient,
TaxClient,
} from "@bitwarden/web-vault/app/billing/clients";
import {
EnterBillingAddressComponent,
@@ -87,7 +87,7 @@ const Allowed2020PlansForLegacyProviders = [
EnterPaymentMethodComponent,
EnterBillingAddressComponent,
],
providers: [SubscriberBillingClient, TaxClient],
providers: [SubscriberBillingClient, PreviewInvoiceClient],
})
export class OrganizationPlansComponent implements OnInit, OnDestroy {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
@@ -219,7 +219,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
private toastService: ToastService,
private accountService: AccountService,
private subscriberBillingClient: SubscriberBillingClient,
private taxClient: TaxClient,
private previewInvoiceClient: PreviewInvoiceClient,
private configService: ConfigService,
) {
this.selfHosted = this.platformUtilsService.isSelfHost();
@@ -793,11 +793,11 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
// by comparing tax on base+storage vs tax on base only
//TODO: Move this logic to PreviewOrganizationTaxCommand - https://bitwarden.atlassian.net/browse/PM-27585
const [baseTaxAmounts, fullTaxAmounts] = await Promise.all([
this.taxClient.previewTaxForOrganizationSubscriptionPurchase(
this.previewInvoiceClient.previewTaxForOrganizationSubscriptionPurchase(
this.buildTaxPreviewRequest(0, false),
billingAddress,
),
this.taxClient.previewTaxForOrganizationSubscriptionPurchase(
this.previewInvoiceClient.previewTaxForOrganizationSubscriptionPurchase(
this.buildTaxPreviewRequest(this.formGroup.value.additionalStorage, false),
billingAddress,
),
@@ -806,10 +806,14 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy {
// Tax on storage = Tax on (base + storage) - Tax on (base only)
this.estimatedTax = fullTaxAmounts.tax - baseTaxAmounts.tax;
} else {
const taxAmounts = await this.taxClient.previewTaxForOrganizationSubscriptionPurchase(
this.buildTaxPreviewRequest(this.formGroup.value.additionalStorage, sponsoredForTaxPreview),
billingAddress,
);
const taxAmounts =
await this.previewInvoiceClient.previewTaxForOrganizationSubscriptionPurchase(
this.buildTaxPreviewRequest(
this.formGroup.value.additionalStorage,
sponsoredForTaxPreview,
),
billingAddress,
);
this.estimatedTax = taxAmounts.tax;
}

View File

@@ -34,7 +34,10 @@ import {
DialogService,
ToastService,
} from "@bitwarden/components";
import { SubscriberBillingClient, TaxClient } from "@bitwarden/web-vault/app/billing/clients";
import {
SubscriberBillingClient,
PreviewInvoiceClient,
} from "@bitwarden/web-vault/app/billing/clients";
import {
EnterBillingAddressComponent,
EnterPaymentMethodComponent,
@@ -73,7 +76,7 @@ interface OnSuccessArgs {
selector: "app-trial-payment-dialog",
templateUrl: "./trial-payment-dialog.component.html",
standalone: false,
providers: [SubscriberBillingClient, TaxClient],
providers: [SubscriberBillingClient, PreviewInvoiceClient],
})
export class TrialPaymentDialogComponent implements OnInit, OnDestroy {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
@@ -118,7 +121,7 @@ export class TrialPaymentDialogComponent implements OnInit, OnDestroy {
private toastService: ToastService,
private organizationBillingApiServiceAbstraction: OrganizationBillingApiServiceAbstraction,
private subscriberBillingClient: SubscriberBillingClient,
private taxClient: TaxClient,
private previewInvoiceClient: PreviewInvoiceClient,
) {
this.initialPaymentMethod = this.dialogParams.initialPaymentMethod ?? PaymentMethodType.Card;
}
@@ -300,7 +303,7 @@ export class TrialPaymentDialogComponent implements OnInit, OnDestroy {
const tier = getTierFromLegacyEnum(this.organization);
if (tier && cadence) {
const costs = await this.taxClient.previewTaxForOrganizationSubscriptionPlanChange(
const costs = await this.previewInvoiceClient.previewTaxForOrganizationSubscriptionPlanChange(
this.organization.id,
{
tier,

View File

@@ -15,7 +15,7 @@ import {
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { ToastService } from "@bitwarden/components";
import { TaxClient } from "@bitwarden/web-vault/app/billing/clients";
import { PreviewInvoiceClient } from "@bitwarden/web-vault/app/billing/clients";
import {
BillingAddressControls,
EnterBillingAddressComponent,
@@ -41,7 +41,7 @@ export interface OrganizationCreatedEvent {
selector: "app-trial-billing-step",
templateUrl: "./trial-billing-step.component.html",
imports: [EnterPaymentMethodComponent, EnterBillingAddressComponent, SharedModule],
providers: [TaxClient, TrialBillingStepService],
providers: [PreviewInvoiceClient, TrialBillingStepService],
})
export class TrialBillingStepComponent implements OnInit, OnDestroy {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals

View File

@@ -12,7 +12,7 @@ import {
import { PaymentMethodType, PlanType } from "@bitwarden/common/billing/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { TaxClient } from "@bitwarden/web-vault/app/billing/clients";
import { PreviewInvoiceClient } from "@bitwarden/web-vault/app/billing/clients";
import {
BillingAddressControls,
getBillingAddressFromControls,
@@ -63,7 +63,7 @@ export class TrialBillingStepService {
private accountService: AccountService,
private apiService: ApiService,
private organizationBillingService: OrganizationBillingServiceAbstraction,
private taxClient: TaxClient,
private previewInvoiceClient: PreviewInvoiceClient,
private configService: ConfigService,
) {}
@@ -129,7 +129,7 @@ export class TrialBillingStepService {
total: number;
}> => {
const billingAddress = getBillingAddressFromControls(billingAddressControls);
return await this.taxClient.previewTaxForOrganizationSubscriptionPurchase(
return await this.previewInvoiceClient.previewTaxForOrganizationSubscriptionPurchase(
{
tier,
cadence,