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 @@ +
+ + {{ "taxIdType" | 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 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 [