From 2cc5f7044a6481a556f7c7765a3fd316c4db9a9e Mon Sep 17 00:00:00 2001 From: Alberto Calvo Date: Sun, 6 Oct 2024 12:10:31 +0200 Subject: [PATCH] feature: update to 2024 tax specs --- src/components/irpf-selector.ts | 4 +-- src/components/net-salary-calculator.ts | 5 ++- src/irpf-table.ts | 39 ---------------------- src/taxes-2024.ts | 43 +++++++++++++++++++++++++ test/irpf-selector.test.ts | 8 ++--- test/net-salary-calculator.test.ts | 10 +++--- 6 files changed, 56 insertions(+), 53 deletions(-) delete mode 100644 src/irpf-table.ts create mode 100644 src/taxes-2024.ts diff --git a/src/components/irpf-selector.ts b/src/components/irpf-selector.ts index 0cd03cd..a7fc400 100644 --- a/src/components/irpf-selector.ts +++ b/src/components/irpf-selector.ts @@ -1,8 +1,8 @@ import { LitElement, PropertyValues, css, html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { inputCheckboxStyles, inputNumberStyles } from '../shared-styles'; +import { IRPF_TABLE } from '../taxes-2024'; import { classMap } from 'lit/directives/class-map.js'; -import irpfTable from '../irpf-table'; @customElement('irpf-selector') export class IrpfSelector extends LitElement { @@ -41,7 +41,7 @@ export class IrpfSelector extends LitElement { willUpdate(changedProperties: PropertyValues) { if (this.automatic) { - const level = irpfTable[Object.keys(irpfTable).find((t) => Number(t) >= this.salary)]; + const level = IRPF_TABLE[Object.keys(IRPF_TABLE).find((t) => Number(t) >= this.salary)]; this.irpf = level[this.descendants] ?? level[level.length - 1]; } if (changedProperties.has('irpf')) { diff --git a/src/components/net-salary-calculator.ts b/src/components/net-salary-calculator.ts index 1929b1a..a98a124 100644 --- a/src/components/net-salary-calculator.ts +++ b/src/components/net-salary-calculator.ts @@ -2,6 +2,7 @@ import './gross-salary-selector'; import './irpf-selector'; import './payments-selector'; import { LitElement, css, html } from 'lit'; +import { MAXIMUM_SS_ANNUAL_QUOTE, SS_CONTRIBUTION_RATE } from '../taxes-2024'; import { customElement, state } from 'lit/decorators.js'; @customElement('net-salary-calculator') @@ -41,8 +42,6 @@ export class NetSalaryCalculator extends LitElement { @state() payments = 12; - MAXIMUM_SS_ANNUAL_QUOTE = 4495.50 * 12; - SS_CONTRIBUTION_RATE = 0.0645; netSalary = 0; private setSalary(event: CustomEvent) { @@ -59,7 +58,7 @@ export class NetSalaryCalculator extends LitElement { willUpdate() { const irpfContribution = this.salary * this.irpf; - const socialSecurityContribution = Math.min(this.salary, this.MAXIMUM_SS_ANNUAL_QUOTE) * this.SS_CONTRIBUTION_RATE; + const socialSecurityContribution = Math.min(this.salary, MAXIMUM_SS_ANNUAL_QUOTE) * SS_CONTRIBUTION_RATE; this.netSalary = (this.salary - irpfContribution - socialSecurityContribution) / this.payments; } diff --git a/src/irpf-table.ts b/src/irpf-table.ts deleted file mode 100644 index 9a88e35..0000000 --- a/src/irpf-table.ts +++ /dev/null @@ -1,39 +0,0 @@ -export default { - 14000: [0], - 15220: [5, 3, 0], - 15980: [6, 4, 1, 0], - 17090: [7, 5, 3, 0], - 18380: [8, 6, 4, 0], - 19730: [9, 7, 5, 2, 0], - 21260: [10, 8, 7, 3, 0], - 23020: [11, 10, 8, 5, 1, 0], - 24340: [12, 11, 9, 6, 3, 0], - 26450: [13, 12, 10, 7, 4, 0], - 28730: [14, 13, 11, 9, 6, 2, 0], - 31440: [15, 14, 13, 10, 8, 4, 0], - 34700: [16, 15, 14, 12, 9, 6, 0], - 39200: [17, 16, 15, 13, 11, 8, 0], - 42730: [18, 17, 16, 15, 13, 10, 2], - 46060: [19, 18, 17, 16, 14, 12, 5], - 49950: [20, 19, 18, 17, 15, 13, 7], - 54440: [21, 20, 20, 18, 17, 15, 9], - 58910: [22, 21, 21, 19, 18, 16, 11], - 62530: [23, 22, 22, 21, 19, 18, 12], - 66690: [24, 23, 23, 22, 21, 19, 14], - 71430: [25, 25, 24, 23, 22, 20, 16], - 76990: [26, 26, 25, 24, 23, 22, 17], - 82800: [27, 27, 26, 25, 24, 23, 19], - 87810: [28, 28, 27, 26, 25, 24, 20], - 93650: [29, 29, 28, 27, 27, 25, 22], - 100330: [30, 30, 29, 29, 28, 27, 23], - 108030: [31, 31, 30, 30, 29, 28, 25], - 116500: [32, 32, 31, 31, 30, 29, 26], - 125820: [33, 33, 32, 32, 31, 30, 28], - 137200: [34, 34, 33, 33, 32, 32, 29], - 150220: [35, 35, 34, 34, 33, 33, 31], - 164530: [36, 36, 36, 35, 35, 34, 32], - 181840: [37, 37, 37, 36, 36, 35, 33], - 203240: [38, 38, 38, 37, 37, 36, 35], - 225470: [39, 39, 39, 38, 38, 37, 36], - Infinity: [40, 40, 40, 39, 39, 39, 37], -}; diff --git a/src/taxes-2024.ts b/src/taxes-2024.ts new file mode 100644 index 0000000..87f2bdb --- /dev/null +++ b/src/taxes-2024.ts @@ -0,0 +1,43 @@ +export const SS_CONTRIBUTION_RATE = 0.0647; + +export const MAXIMUM_SS_ANNUAL_QUOTE = 4720.50 * 12; + +export const IRPF_TABLE = { + 14000: [0], + 15410: [5, 3, 0], + 16230: [6, 4, 1, 0], + 17370: [7, 5, 3, 0], + 18680: [8, 6, 4, 0], + 19970: [9, 7, 5, 2, 0], + 21520: [10, 8, 6, 3, 0], + 23350: [11, 10, 8, 5, 1, 0], + 24970: [12, 11, 9, 6, 3, 0], + 26930: [13, 12, 10, 7, 4, 0], + 29260: [14, 13, 11, 9, 6, 2, 0], + 32010: [15, 14, 13, 10, 8, 4, 0], + 35330: [16, 15, 14, 12, 9, 6, 0], + 39900: [17, 16, 15, 13, 11, 8, 0], + 43590: [18, 17, 16, 15, 13, 10, 2], + 46980: [19, 18, 17, 16, 14, 12, 4], + 50950: [20, 19, 18, 17, 15, 13, 7], + 55350: [21, 20, 20, 18, 17, 15, 9], + 59890: [22, 21, 21, 19, 18, 16, 11], + 63800: [23, 22, 22, 21, 19, 18, 12], + 68040: [24, 23, 23, 22, 21, 19, 14], + 72840: [25, 25, 24, 23, 22, 20, 16], + 78390: [26, 26, 25, 24, 23, 22, 17], + 84410: [27, 27, 26, 25, 24, 23, 19], + 89690: [28, 28, 27, 26, 25, 24, 20], + 95680: [29, 29, 28, 27, 27, 25, 22], + 102280: [30, 30, 29, 29, 28, 27, 23], + 110120: [31, 31, 30, 30, 29, 28, 25], + 118780: [32, 32, 31, 31, 30, 29, 26], + 128700: [33, 33, 32, 32, 31, 30, 28], + 139880: [34, 34, 33, 33, 32, 32, 29], + 153200: [35, 35, 34, 34, 33, 33, 31], + 167790: [36, 36, 36, 35, 35, 34, 32], + 185460: [37, 37, 37, 36, 36, 35, 33], + 207280: [38, 38, 38, 37, 37, 36, 35], + 230150: [39, 39, 39, 38, 38, 37, 36], + Infinity: [40, 40, 40, 39, 39, 39, 37], +}; diff --git a/test/irpf-selector.test.ts b/test/irpf-selector.test.ts index 1a99779..b8f1dca 100644 --- a/test/irpf-selector.test.ts +++ b/test/irpf-selector.test.ts @@ -34,8 +34,8 @@ describe('irpf-selector', () => { while (el.isUpdatePending) { await el.updateComplete; } - expect(detail.irpf).to.equal(21); - expect(irpfInput.value).to.equal('21'); + expect(detail.irpf).to.equal(20); + expect(irpfInput.value).to.equal('20'); }); it('50000 salary, automatic irpf, 4 descendants', async () => { @@ -50,8 +50,8 @@ describe('irpf-selector', () => { while (el.isUpdatePending) { await el.updateComplete; } - expect(detail.irpf).to.equal(17); - expect(irpfInput.value).to.equal('17'); + expect(detail.irpf).to.equal(15); + expect(irpfInput.value).to.equal('15'); }); it('50000 salary, 20% IRPF', async () => { diff --git a/test/net-salary-calculator.test.ts b/test/net-salary-calculator.test.ts index e942c1b..fa355b2 100644 --- a/test/net-salary-calculator.test.ts +++ b/test/net-salary-calculator.test.ts @@ -45,7 +45,7 @@ describe('net-salary-calculator', () => { while (el.isUpdatePending) { await el.updateComplete; } - expect(el.shadowRoot.innerHTML).contains('1392,50'); + expect(el.shadowRoot.innerHTML).contains('1392,17'); }); it('40000 salary, automatic IPRF, 2 descendants, 14 payments', async () => { @@ -63,7 +63,7 @@ describe('net-salary-calculator', () => { while (el.isUpdatePending) { await el.updateComplete; } - expect(el.shadowRoot.innerHTML).contains('2215,71'); + expect(el.shadowRoot.innerHTML).contains('2215,14'); }); it('60000 salary, automatic IPRF, 4 descendants, 12 payments', async () => { @@ -78,7 +78,7 @@ describe('net-salary-calculator', () => { while (el.isUpdatePending) { await el.updateComplete; } - expect(el.shadowRoot.innerHTML).contains('3760,04'); + expect(el.shadowRoot.innerHTML).contains('3744,58'); }); it('80000 salary, 25% IPRF, 14 payments', async () => { @@ -99,7 +99,7 @@ describe('net-salary-calculator', () => { while (el.isUpdatePending) { await el.updateComplete; } - expect(el.shadowRoot.innerHTML).contains('4037,18'); + expect(el.shadowRoot.innerHTML).contains('4023,93'); }); it('1000000000 salary, automatic IRPF, 100 descendants, 12 payments', async () => { @@ -114,7 +114,7 @@ describe('net-salary-calculator', () => { while (el.isUpdatePending) { await el.updateComplete; } - expect(el.shadowRoot.innerHTML).contains('52.499.710,04'); + expect(el.shadowRoot.innerHTML).contains('52.499.694,58'); }); }); });