From e19621c7517c0c394e2ce3cfb28f87fa10b6ad3b Mon Sep 17 00:00:00 2001 From: Stephon Brown Date: Tue, 20 Jan 2026 11:08:45 -0500 Subject: [PATCH] fix(billing)!: rename tax-client in components --- .../unified-upgrade-dialog.component.ts | 4 +- .../services/upgrade-payment.service.spec.ts | 45 +++++++++++-------- .../services/upgrade-payment.service.ts | 26 ++++++----- .../change-plan-dialog.component.ts | 17 +++---- .../organization-plans.component.ts | 22 +++++---- .../trial-payment-dialog.component.ts | 11 +++-- .../trial-billing-step.component.ts | 4 +- .../trial-billing-step.service.ts | 6 +-- 8 files changed, 77 insertions(+), 58 deletions(-) diff --git a/apps/web/src/app/billing/individual/upgrade/unified-upgrade-dialog/unified-upgrade-dialog.component.ts b/apps/web/src/app/billing/individual/upgrade/unified-upgrade-dialog/unified-upgrade-dialog.component.ts index 222bf77715c..63017760195 100644 --- a/apps/web/src/app/billing/individual/upgrade/unified-upgrade-dialog/unified-upgrade-dialog.component.ts +++ b/apps/web/src/app/billing/individual/upgrade/unified-upgrade-dialog/unified-upgrade-dialog.component.ts @@ -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 { diff --git a/apps/web/src/app/billing/individual/upgrade/upgrade-payment/services/upgrade-payment.service.spec.ts b/apps/web/src/app/billing/individual/upgrade/upgrade-payment/services/upgrade-payment.service.spec.ts index 83440646b48..bbb89bd622f 100644 --- a/apps/web/src/app/billing/individual/upgrade/upgrade-payment/services/upgrade-payment.service.spec.ts +++ b/apps/web/src/app/billing/individual/upgrade/upgrade-payment/services/upgrade-payment.service.spec.ts @@ -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(); const mockAccountBillingClient = mock(); - const mockTaxClient = mock(); + const mockPreviewInvoiceClient = mock(); const mockLogService = mock(); const mockSyncService = mock(); const mockOrganizationService = mock(); @@ -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(); 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(); 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), diff --git a/apps/web/src/app/billing/individual/upgrade/upgrade-payment/services/upgrade-payment.service.ts b/apps/web/src/app/billing/individual/upgrade/upgrade-payment/services/upgrade-payment.service.ts index b8d5637e471..4140a202b1e 100644 --- a/apps/web/src/app/billing/individual/upgrade/upgrade-payment/services/upgrade-payment.service.ts +++ b/apps/web/src/app/billing/individual/upgrade/upgrade-payment/services/upgrade-payment.service.ts @@ -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 | null = null; + let previewInvoiceClientCall: Promise | 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); diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts index d14f627127a..0a22ef5ddac 100644 --- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts @@ -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; } diff --git a/apps/web/src/app/billing/organizations/organization-plans.component.ts b/apps/web/src/app/billing/organizations/organization-plans.component.ts index 67f6f9b0a6b..3364ce2cbea 100644 --- a/apps/web/src/app/billing/organizations/organization-plans.component.ts +++ b/apps/web/src/app/billing/organizations/organization-plans.component.ts @@ -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; } diff --git a/apps/web/src/app/billing/shared/trial-payment-dialog/trial-payment-dialog.component.ts b/apps/web/src/app/billing/shared/trial-payment-dialog/trial-payment-dialog.component.ts index 64af7be948e..19ccbf28ee9 100644 --- a/apps/web/src/app/billing/shared/trial-payment-dialog/trial-payment-dialog.component.ts +++ b/apps/web/src/app/billing/shared/trial-payment-dialog/trial-payment-dialog.component.ts @@ -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, diff --git a/apps/web/src/app/billing/trial-initiation/trial-billing-step/trial-billing-step.component.ts b/apps/web/src/app/billing/trial-initiation/trial-billing-step/trial-billing-step.component.ts index 04ee7931cf3..9b86a9ba81b 100644 --- a/apps/web/src/app/billing/trial-initiation/trial-billing-step/trial-billing-step.component.ts +++ b/apps/web/src/app/billing/trial-initiation/trial-billing-step/trial-billing-step.component.ts @@ -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 diff --git a/apps/web/src/app/billing/trial-initiation/trial-billing-step/trial-billing-step.service.ts b/apps/web/src/app/billing/trial-initiation/trial-billing-step/trial-billing-step.service.ts index 0888ef07afc..99eaf5c7988 100644 --- a/apps/web/src/app/billing/trial-initiation/trial-billing-step/trial-billing-step.service.ts +++ b/apps/web/src/app/billing/trial-initiation/trial-billing-step/trial-billing-step.service.ts @@ -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,