1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-12 14:34:02 +00:00

[PM-14892] Refactoring tax estimation

This commit is contained in:
Jonas Hendrickx
2024-11-18 09:12:32 +01:00
parent 16613207a2
commit 52e7c26332
7 changed files with 72 additions and 2 deletions

View File

@@ -33,6 +33,18 @@
<input bitInput type="text" formControlName="taxId" />
</bit-form-field>
</div>
<div class="tw-col-span-6">
<bit-form-field>
<bit-label>{{ "taxIdType" | i18n }}</bit-label>
<bit-select formControlName="taxIdType">
<bit-option
*ngFor="let taxIdType of taxIdTypes"
[value]="taxIdType.code"
[label]="taxIdType.description"
/>
</bit-select>
</bit-form-field>
</div>
</div>
<div class="tw-grid tw-grid-cols-12 tw-gap-4" *ngIf="showTaxIdFields">
<div class="tw-col-span-6">

View File

@@ -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();
}

View File

@@ -4655,6 +4655,9 @@
"taxIdNumber": {
"message": "VAT/GST Tax ID"
},
"taxIdType": {
"message": "Tax ID Type"
},
"taxInfoUpdated": {
"message": "Tax information updated."
},

View File

@@ -1261,7 +1261,7 @@ const safeProviders: SafeProvider[] = [
safeProvider({
provide: TaxServiceAbstraction,
useClass: TaxService,
deps: [],
deps: [ApiServiceAbstraction],
}),
safeProvider({
provide: BillingAccountProfileStateService,

View File

@@ -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<TaxIdTypesResponse>;
getCountries: () => CountryListItem[];
/**

View File

@@ -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");
}
}

View File

@@ -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<TaxIdTypesResponse> {
const response = await this.apiService.send("GET", "/tax/id-types", null, true, true);
return new TaxIdTypesResponse(response);
}
getCountries(): CountryListItem[] {
return [