forked from samh21/calculate.this
-
Notifications
You must be signed in to change notification settings - Fork 0
/
takeHomeSalary.js
178 lines (148 loc) · 4.66 KB
/
takeHomeSalary.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// Globals
// Tax bands
const PERSONAL_ALLOWANCE = 12500;
const BASIC_RATE = { VALUE: 37500, RATE: 0.2 };
const HIGHER_RATE = { VALUE: 150000, RATE: 0.4 };
const ADDITIONAL_RATE = { RATE: 0.45 };
// National Insurance thresholds
const NI_BASE = { VALUE: 9500, RATE: 0.12 };
const NI_UPPER = { VALUE: 50000, RATE: 0.02 };
let salary;
// Currency formatter.
let currency = new Intl.NumberFormat('en-UK', {
style: 'currency',
currency: 'GBP',
minimumFractionDigits: 0,
maximumFractionDigits: 0,
});
// Form event listener
document.getElementById('salary-form').addEventListener('submit', handleSubmit);
function handleSubmit(e) {
e.preventDefault();
document.getElementById('results').style.display = 'none';
salary = document.getElementById('salary').value;
if (!salary) {
displayError();
return;
}
if (document.getElementById(alert))
document.getElementById('alert').outerHTML = '';
document.getElementById('spinner').style.display = 'block';
setTimeout(calculateResults, 1500);
}
// Calculate Results
function calculateResults() {
document.getElementById('spinner').style.display = 'none';
const personalTaxAllowance = getPersonalAllowance(salary);
const tax = calculateTax(salary, personalTaxAllowance);
const nationalInsurance = calculateNI(salary);
let totalIncome = [];
let totalTaxableIncome = [];
let totalTax = [];
let totalNationalInsurance = [];
let totalTakeHome = [];
createArrays(totalIncome, salary);
createArrays(totalTaxableIncome, salary - getPersonalAllowance(salary));
createArrays(totalTax, tax.basicRate + tax.higherRate + tax.additionalRate);
createArrays(
totalNationalInsurance,
nationalInsurance.basic + nationalInsurance.upper
);
createArrays(
totalTakeHome,
salary -
nationalInsurance.basic -
nationalInsurance.upper -
tax.basicRate -
tax.higherRate -
tax.additionalRate
);
updateDOM(document.getElementById('gross-income').children, totalIncome);
updateDOM(
document.getElementById('taxable-income').children,
totalTaxableIncome
);
updateDOM(document.getElementById('tax').children, totalTax);
updateDOM(
document.getElementById('national-insurance').children,
totalNationalInsurance
);
updateDOM(document.getElementById('take-home').children, totalTakeHome);
document.getElementById('results').style.display = 'block';
}
// Determine tax free personal allowance
function getPersonalAllowance(grossSalary) {
if (grossSalary < PERSONAL_ALLOWANCE) return Number(grossSalary);
if (grossSalary <= 100000) return PERSONAL_ALLOWANCE;
// Personal allowance decreases by £1 for each £2 earned
// above £100,000 until it reaches zero
if (grossSalary <= 125000) {
const decrease = Math.floor((grossSalary - 100000) / 2);
return Number(PERSONAL_ALLOWANCE - decrease);
}
// no personal allowance for salart over £125,000
return 0;
}
function calculateTax(salary, personalAllowance) {
const tax = {
basicRate: null,
higherRate: null,
additionalRate: null,
};
tax.basicRate = Math.max(
(Math.min(salary, BASIC_RATE.VALUE + PERSONAL_ALLOWANCE) -
PERSONAL_ALLOWANCE) *
BASIC_RATE.RATE,
0
);
tax.higherRate = Math.max(
(Math.min(salary, HIGHER_RATE.VALUE) -
BASIC_RATE.VALUE -
personalAllowance) *
HIGHER_RATE.RATE,
0
);
tax.additionalRate =
salary > HIGHER_RATE.VALUE
? (salary - HIGHER_RATE.VALUE) * ADDITIONAL_RATE.RATE
: 0;
return tax;
}
function calculateNI(salary) {
const nationalInsurance = {
basic: null,
upper: null,
};
nationalInsurance.basic = Math.max(
(Math.min(salary, NI_UPPER.VALUE) - NI_BASE.VALUE) * NI_BASE.RATE,
0
);
nationalInsurance.upper =
salary > NI_UPPER.VALUE ? (salary - NI_UPPER.VALUE) * NI_UPPER.RATE : 0;
return nationalInsurance;
}
// Create arrays to contain yearly, monthly, weekly and daily totals
function createArrays(array, value) {
array.push(currency.format(value));
array.push(currency.format(value / 12));
array.push(currency.format(value / 52));
array.push(currency.format(value / 260));
}
// Update DOM table elements
function updateDOM(element, array) {
for (let i = 1; i < array.length + 1; i++) {
element[i].textContent = array[i - 1];
}
}
// Show error if no value entered
function displayError() {
const alert = document.createElement('div');
alert.className = 'alert alert-danger py-1 mt-2';
alert.id = 'alert';
alert.appendChild(document.createTextNode('Please enter a salary'));
document.querySelector('div.form-group').appendChild(alert);
setTimeout(removeError, 3000);
}
function removeError() {
document.getElementById('alert').outerHTML = '';
}