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 82d5104a53a..06f790ba26b 100644
--- a/apps/web/src/app/billing/shared/tax-info.component.html
+++ b/apps/web/src/app/billing/shared/tax-info.component.html
@@ -33,6 +33,18 @@
+
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 84531a57ebd..558857834eb 100644
--- a/apps/web/src/app/billing/shared/tax-info.component.ts
+++ b/apps/web/src/app/billing/shared/tax-info.component.ts
@@ -9,6 +9,7 @@ import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/ta
import { CountryListItem } from "@bitwarden/common/billing/models/domain";
import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request";
import { TaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/tax-info-update.request";
+import { TaxIdTypeResponse } from "@bitwarden/common/billing/models/response/tax-id-types.response";
import { TaxInfoResponse } from "@bitwarden/common/billing/models/response/tax-info.response";
import { TaxRateResponse } from "@bitwarden/common/billing/models/response/tax-rate.response";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
@@ -37,6 +38,7 @@ export class TaxInfoComponent implements OnInit {
postalCode: new FormControl(null),
includeTaxId: new FormControl(null),
taxId: new FormControl(null),
+ taxIdType: new FormControl(null),
line1: new FormControl(null),
line2: new FormControl(null),
city: new FormControl(null),
@@ -58,6 +60,7 @@ export class TaxInfoComponent implements OnInit {
};
countryList: CountryListItem[] = this.taxService.getCountries();
taxRates: TaxRateResponse[];
+ taxIdTypes: TaxIdTypeResponse[];
constructor(
private apiService: ApiService,
@@ -207,6 +210,10 @@ export class TaxInfoComponent implements OnInit {
if (taxRates) {
this.taxRates = taxRates.data;
}
+ const taxIdTypes = await this.taxService.getTaxIdTypes();
+ if (taxIdTypes) {
+ this.taxIdTypes = taxIdTypes.taxIdTypes;
+ }
} catch (e) {
this.logService.error(e);
} finally {
@@ -300,6 +307,16 @@ export class TaxInfoComponent implements OnInit {
this.state = null;
this.setTaxInfoObject();
}
+ // reorder tax id types based on country
+ this.taxIdTypes = this.taxIdTypes.sort((a, b) => {
+ if (a.country === this.country && b.country !== this.country) {
+ return -1;
+ } else if (a.country !== this.country && b.country === this.country) {
+ return 1;
+ } else {
+ return a.description.localeCompare(b.description);
+ }
+ });
this.onCountryChanged.emit();
}
diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json
index 00d2102c786..e365e6a6105 100644
--- a/apps/web/src/locales/en/messages.json
+++ b/apps/web/src/locales/en/messages.json
@@ -4655,6 +4655,9 @@
"taxIdNumber": {
"message": "VAT/GST Tax ID"
},
+ "taxIdType": {
+ "message": "Tax ID Type"
+ },
"taxInfoUpdated": {
"message": "Tax information updated."
},
diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts
index b95b346884f..57cf55d9c76 100644
--- a/libs/angular/src/services/jslib-services.module.ts
+++ b/libs/angular/src/services/jslib-services.module.ts
@@ -1261,7 +1261,7 @@ const safeProviders: SafeProvider[] = [
safeProvider({
provide: TaxServiceAbstraction,
useClass: TaxService,
- deps: [],
+ deps: [ApiServiceAbstraction],
}),
safeProvider({
provide: BillingAccountProfileStateService,
diff --git a/libs/common/src/billing/abstractions/tax.service.abstraction.ts b/libs/common/src/billing/abstractions/tax.service.abstraction.ts
index d85aaddd9c9..6ecc0208d8e 100644
--- a/libs/common/src/billing/abstractions/tax.service.abstraction.ts
+++ b/libs/common/src/billing/abstractions/tax.service.abstraction.ts
@@ -1,6 +1,9 @@
import { CountryListItem } from "@bitwarden/common/billing/models/domain";
+import { TaxIdTypesResponse } from "@bitwarden/common/billing/models/response/tax-id-types.response";
export abstract class TaxServiceAbstraction {
+ getTaxIdTypes: () => Promise;
+
getCountries: () => CountryListItem[];
/**
diff --git a/libs/common/src/billing/models/response/tax-id-types.response.ts b/libs/common/src/billing/models/response/tax-id-types.response.ts
new file mode 100644
index 00000000000..0d5cce46c8c
--- /dev/null
+++ b/libs/common/src/billing/models/response/tax-id-types.response.ts
@@ -0,0 +1,28 @@
+import { BaseResponse } from "@bitwarden/common/models/response/base.response";
+
+export class TaxIdTypesResponse extends BaseResponse {
+ taxIdTypes: TaxIdTypeResponse[] = [];
+
+ constructor(response: any) {
+ super(response);
+ const taxIdTypes = this.getResponseProperty("TaxIdTypes");
+ if (taxIdTypes && taxIdTypes.length) {
+ this.taxIdTypes = taxIdTypes.map((t: any) => new TaxIdTypeResponse(t));
+ }
+ }
+}
+
+export class TaxIdTypeResponse extends BaseResponse {
+ code: string;
+ country: string;
+ description: string;
+ example: string;
+
+ constructor(response: any) {
+ super(response);
+ this.code = this.getResponseProperty("Code");
+ this.country = this.getResponseProperty("Country");
+ this.description = this.getResponseProperty("Description");
+ this.example = this.getResponseProperty("Example");
+ }
+}
diff --git a/libs/common/src/billing/services/tax.service.ts b/libs/common/src/billing/services/tax.service.ts
index 68c21d2f7fb..ed4b7c476a6 100644
--- a/libs/common/src/billing/services/tax.service.ts
+++ b/libs/common/src/billing/services/tax.service.ts
@@ -1,8 +1,15 @@
+import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction";
import { CountryListItem } from "@bitwarden/common/billing/models/domain";
+import { TaxIdTypesResponse } from "@bitwarden/common/billing/models/response/tax-id-types.response";
export class TaxService implements TaxServiceAbstraction {
- constructor() {}
+ constructor(private apiService: ApiService) {}
+
+ async getTaxIdTypes(): Promise {
+ const response = await this.apiService.send("GET", "/tax/id-types", null, true, true);
+ return new TaxIdTypesResponse(response);
+ }
getCountries(): CountryListItem[] {
return [