diff --git a/apps/web/src/app/billing/shared/tax-info.component.html b/apps/web/src/app/billing/shared/tax-info.component.html
index 7bd38c278be..7bd48ffb4fe 100644
--- a/apps/web/src/app/billing/shared/tax-info.component.html
+++ b/apps/web/src/app/billing/shared/tax-info.component.html
@@ -19,7 +19,7 @@
-
+
{{ "includeVAT" | i18n }}
diff --git a/apps/web/src/app/billing/shared/tax-info.component.ts b/apps/web/src/app/billing/shared/tax-info.component.ts
index 0f23d308a0e..c2a84caa80f 100644
--- a/apps/web/src/app/billing/shared/tax-info.component.ts
+++ b/apps/web/src/app/billing/shared/tax-info.component.ts
@@ -40,12 +40,13 @@ export class TaxInfoComponent implements OnInit, OnDestroy {
state: new FormControl(null),
});
+ protected isTaxSupported: boolean;
+
loading = true;
organizationId: string;
providerId: string;
countryList: CountryListItem[] = this.taxService.getCountries();
taxRates: TaxRateResponse[];
- private taxSupportedCountryCodes: string[] = this.taxService.getSupportedCountries();
constructor(
private apiService: ApiService,
@@ -109,12 +110,11 @@ export class TaxInfoComponent implements OnInit, OnDestroy {
this.taxFormGroup.controls.postalCode.setValue(taxInfo.postalCode);
this.taxFormGroup.controls.country.setValue(taxInfo.country || "US");
this.taxFormGroup.controls.includeTaxId.setValue(
- this.countrySupportsTax(this.country) &&
- (!!taxInfo.taxId ||
- !!taxInfo.line1 ||
- !!taxInfo.line2 ||
- !!taxInfo.city ||
- !!taxInfo.state),
+ !!taxInfo.taxId ||
+ !!taxInfo.line1 ||
+ !!taxInfo.line2 ||
+ !!taxInfo.city ||
+ !!taxInfo.state,
);
}
} catch (e) {
@@ -132,6 +132,10 @@ export class TaxInfoComponent implements OnInit, OnDestroy {
}
}
+ this.isTaxSupported = await this.taxService.isCountrySupported(
+ this.taxFormGroup.controls.country.value,
+ );
+
if (this.country === "US") {
this.taxFormGroup.controls.postalCode.setValidators([Validators.required]);
this.taxFormGroup.controls.postalCode.updateValueAndValidity();
@@ -200,7 +204,7 @@ export class TaxInfoComponent implements OnInit, OnDestroy {
}
get showTaxIdFields(): boolean {
- return this.includeTaxId && this.countrySupportsTax(this.country);
+ return this.includeTaxId && this.isTaxSupported;
}
getTaxInfoRequest(): TaxInfoUpdateRequest {
@@ -227,13 +231,23 @@ export class TaxInfoComponent implements OnInit, OnDestroy {
: this.apiService.putTaxInfo(request);
}
- changeCountry() {
- if (!this.countrySupportsTax(this.country)) {
- this.taxFormGroup.controls.includeTaxId.setValue(false);
- this.clearTaxInformationFields();
- }
+ changeCountry(): void {
+ this.taxService
+ .isCountrySupported(this.taxFormGroup.controls.country.value)
+ .then((isSupported) => {
+ this.isTaxSupported = isSupported;
+ })
+ .catch(() => {
+ this.isTaxSupported = false;
+ })
+ .finally(() => {
+ if (!this.isTaxSupported) {
+ this.taxFormGroup.controls.includeTaxId.setValue(false);
+ this.clearTaxInformationFields();
+ }
- this.onCountryChanged.emit();
+ this.onCountryChanged.emit();
+ });
}
private clearTaxInformationFields(): void {
@@ -243,8 +257,4 @@ export class TaxInfoComponent implements OnInit, OnDestroy {
this.taxFormGroup.controls.city.setValue(null);
this.taxFormGroup.controls.state.setValue(null);
}
-
- countrySupportsTax(countryCode: string) {
- return this.taxSupportedCountryCodes.includes(countryCode);
- }
}
diff --git a/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.ts b/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.ts
index d1eb8453a53..eb44c6df89c 100644
--- a/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.ts
+++ b/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.ts
@@ -26,6 +26,8 @@ export class ManageTaxInformationComponent implements OnInit, OnDestroy {
state: "",
});
+ isTaxSupported: boolean;
+
private destroy$ = new Subject();
protected readonly countries: CountryListItem[] = this.taxService.getCountries();
@@ -61,7 +63,7 @@ export class ManageTaxInformationComponent implements OnInit, OnDestroy {
this.formGroup.patchValue({
...this.startWith,
includeTaxId:
- this.countrySupportsTax(this.startWith.country) &&
+ this.isTaxSupported &&
(!!this.startWith.taxId ||
!!this.startWith.line1 ||
!!this.startWith.line2 ||
@@ -81,7 +83,13 @@ export class ManageTaxInformationComponent implements OnInit, OnDestroy {
city: values.city,
state: values.state,
};
+ this.taxService
+ .isCountrySupported(this.taxInformation.country)
+ .then((isSupported) => (this.isTaxSupported = isSupported))
+ .catch(() => (this.isTaxSupported = false));
});
+
+ this.isTaxSupported = await this.taxService.isCountrySupported(this.taxInformation.country);
}
ngOnDestroy() {
@@ -89,17 +97,11 @@ export class ManageTaxInformationComponent implements OnInit, OnDestroy {
this.destroy$.complete();
}
- protected countrySupportsTax(countryCode: string) {
- return this.taxService.getSupportedCountries().includes(countryCode);
- }
-
protected get includeTaxIdIsSelected() {
return this.formGroup.value.includeTaxId;
}
protected get selectionSupportsAdditionalOptions() {
- return (
- this.formGroup.value.country !== "US" && this.countrySupportsTax(this.formGroup.value.country)
- );
+ return this.formGroup.value.country !== "US" && this.isTaxSupported;
}
}
diff --git a/libs/common/src/billing/abstractions/tax.service.abstraction.ts b/libs/common/src/billing/abstractions/tax.service.abstraction.ts
index 60a80612903..8deb9dbc835 100644
--- a/libs/common/src/billing/abstractions/tax.service.abstraction.ts
+++ b/libs/common/src/billing/abstractions/tax.service.abstraction.ts
@@ -5,10 +5,7 @@ import { PreviewInvoiceResponse } from "@bitwarden/common/billing/models/respons
export abstract class TaxServiceAbstraction {
getCountries: () => CountryListItem[];
- /**
- * Whether the country supports tax.
- */
- getSupportedCountries: () => string[];
+ isCountrySupported: (country: string) => Promise;
previewIndividualInvoice: (
request: PreviewIndividualInvoiceRequest,
diff --git a/libs/common/src/billing/services/tax.service.ts b/libs/common/src/billing/services/tax.service.ts
index f311ba994d9..f9153e9c41c 100644
--- a/libs/common/src/billing/services/tax.service.ts
+++ b/libs/common/src/billing/services/tax.service.ts
@@ -263,82 +263,15 @@ export class TaxService implements TaxServiceAbstraction {
];
}
- getSupportedCountries(): string[] {
- return [
- "CN",
- "FR",
- "DE",
- "CA",
- "GB",
- "AU",
- "IN",
- "AD",
- "AR",
- "AT",
- "BE",
- "BO",
- "BR",
- "BG",
- "CL",
- "CO",
- "CR",
- "HR",
- "CY",
- "CZ",
- "DK",
- "DO",
- "EC",
- "EG",
- "SV",
- "EE",
- "FI",
- "GE",
- "GR",
- "HK",
- "HU",
- "IS",
- "ID",
- "IQ",
- "IE",
- "IL",
- "IT",
- "JP",
- "KE",
- "KR",
- "LV",
- "LI",
- "LT",
- "LU",
- "MY",
- "MT",
- "MX",
- "NL",
- "NZ",
- "NO",
- "PE",
- "PH",
- "PL",
- "PT",
- "RO",
- "RU",
- "SA",
- "RS",
- "SG",
- "SK",
- "SI",
- "ZA",
- "ES",
- "SE",
- "CH",
- "TW",
- "TH",
- "TR",
- "UA",
- "AE",
- "UY",
- "VE",
- "VN",
- ];
+ async isCountrySupported(country: string): Promise {
+ const response = await this.apiService.send(
+ "GET",
+ "/tax/is-country-supported?country=" + country,
+ null,
+ true,
+ true,
+ );
+ return response;
}
async previewIndividualInvoice(