nortax-ts
Version:
Norwegian Tax Calculator - TypeScript Implementation
100 lines (99 loc) • 3.75 kB
JavaScript
;
/**
* nortax-ts
* A TypeScript port of nortax (https://github.com/lewiuberg/nortax)
* Original Copyright (c) 2023 Lewi Lie Uberg
* TypeScript port Copyright (c) 2024 Arild Langtind
* Licensed under the MIT License
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Tax = void 0;
const types_1 = require("./types");
const constants_1 = require("./constants");
const errors_1 = require("./errors");
class Tax {
constructor(grossIncome = 0, taxTable = '7100', incomeType = 'Wage', period = 'Monthly', year = 2024) {
if (!(0, types_1.isValidTableForYear)(taxTable, year)) {
throw new Error(`Invalid tax table "${taxTable}" for year ${year}`);
}
this.grossIncome = Math.round(grossIncome);
this.taxTable = taxTable;
this.incomeType = incomeType;
this.period = period;
this.year = year;
this.returnWholeTable = false;
this.url = '';
}
async makeApiCall(url) {
let response;
try {
response = await fetch(url);
}
catch (error) {
throw new errors_1.TaxNetworkError(`Failed to fetch tax data: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
if (!response.ok) {
throw new errors_1.TaxApiError(`API call failed: ${response.statusText}`);
}
try {
const data = await response.json();
return data === null ? 0 : data;
}
catch (error) {
throw new errors_1.TaxApiError(`Invalid JSON response: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
updateUrl() {
const baseUrl = this.returnWholeTable ? constants_1.TABLE_URL : constants_1.CALCULATE_URL;
this.url =
`${baseUrl}?` +
`${constants_1.ALIASES.chosenTable}=${this.taxTable}&` +
`${constants_1.ALIASES.chosenIncomeType}=${this.incomeType === 'Wage' ? 'LONN' : 'PENSJON'}&` +
`${constants_1.ALIASES.chosenPeriod}=${constants_1.PERIODS[this.period]}&` +
`${constants_1.ALIASES.chosenYear}=${this.year}`;
if (!this.returnWholeTable) {
this.url += `&${constants_1.ALIASES.chosenIncome}=${this.grossIncome}`;
}
}
async getDeduction() {
this.returnWholeTable = false;
this.updateUrl();
const data = await this.makeApiCall(this.url);
return parseInt(data);
}
async getNetIncome() {
const deduction = await this.getDeduction();
return this.grossIncome - deduction;
}
async getWholeTable() {
this.returnWholeTable = true;
this.updateUrl();
const data = await this.makeApiCall(this.url);
this.returnWholeTable = false;
return data.alleTrekk;
}
async getFullDetails() {
const deduction = await this.getDeduction();
const netIncome = await this.getNetIncome();
return `URL: str = ${this.url}
Tax table: valid_tables = ${this.taxTable}
Income type: income_type = ${this.incomeType}
Period: period = ${this.period}
Year: int = ${this.year}
Gross income: int = ${this.grossIncome}
Tax deduction: int = ${deduction}
Net income: int = ${netIncome}`;
}
toString() {
return `URL: str = ${this.url}
Tax table: valid_tables = ${this.taxTable}
Income type: income_type = ${this.incomeType}
Period: period = ${this.period}
Year: int = ${this.year}
Gross income: int = ${this.grossIncome}`;
}
[Symbol.toStringTag]() {
return `Tax(gross_income=${this.grossIncome}, tax_table="${this.taxTable}", income_type="${this.incomeType}", period="${this.period}", year=${this.year})`;
}
}
exports.Tax = Tax;