diff --git a/__tests__/hypoteka.test.ts b/__tests__/hypoteka.test.ts index 4b30038f..02a7240f 100644 --- a/__tests__/hypoteka.test.ts +++ b/__tests__/hypoteka.test.ts @@ -1,42 +1,133 @@ -import { validate } from '../src/pages/hypoteka' +import { TAX_YEAR } from '../src/lib/calculation' +import { validate } from '../src/pages/uroky' import { testValidation } from './utils/testValidation' -describe('hypoteka', () => { +describe.only('hypoteka', () => { describe('#validate', () => { testValidation(validate, [ { - input: { r037_uplatnuje_uroky: undefined }, - expected: ['r037_uplatnuje_uroky'], + input: { r035_uplatnuje_uroky: undefined }, + expected: ['r035_uplatnuje_uroky'], }, - { input: { r037_uplatnuje_uroky: false }, expected: [] }, + { input: { r035_uplatnuje_uroky: false }, expected: [] }, { - input: { r037_uplatnuje_uroky: true }, - expected: ['r037_zaplatene_uroky', 'r037_pocetMesiacov'], + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 1, + }, + expected: ['uroky_dalsi_uver_uplatnuje'], + }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 2, + }, + expected: ['uroky_rok_uzatvorenia', 'uroky_zaciatok_urocenia_den', 'uroky_zaciatok_urocenia_mesiac', 'uroky_zaciatok_urocenia_rok'], + }, + { + input: { + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: TAX_YEAR-1, + hypoteka_step: 2, + }, + expected: ['uroky_zaciatok_urocenia_den', 'uroky_zaciatok_urocenia_mesiac', 'uroky_zaciatok_urocenia_rok'], + }, + { + input: { + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: TAX_YEAR-1, + uroky_zaciatok_urocenia_den: '1', + uroky_zaciatok_urocenia_mesiac: '1', + uroky_zaciatok_urocenia_rok: TAX_YEAR-1, + hypoteka_step: 2, + }, + expected: [], + }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 3, + }, + expected: ['uroky_dalsi_dlznik'], + }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 3, + uroky_dalsi_dlznik: true, + }, + expected: ['uroky_pocet_dlznikov'], + }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 3, + uroky_dalsi_dlznik: false, + }, + expected: [], }, { input: { - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: 'a', - r037_pocetMesiacov: 'b', + r035_uplatnuje_uroky: true, + hypoteka_step: 4, }, - expected: ['r037_zaplatene_uroky', 'r037_pocetMesiacov'], + expected: ['uroky_splnam_vek_kriteria'], }, { input: { - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '10', - r037_pocetMesiacov: '20', + r035_uplatnuje_uroky: true, + hypoteka_step: 4, + uroky_splnam_vek_kriteria: true, }, - expected: ['r037_pocetMesiacov'], + expected: [], }, { input: { - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '10', - r037_pocetMesiacov: '12', + r035_uplatnuje_uroky: true, + hypoteka_step: 5, + }, + expected: ['uroky_splnam_prijem'], + }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 5, + uroky_splnam_prijem: true, }, expected: [], }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 6, + r035_zaplatene_uroky: undefined, + }, + expected: ['r035_zaplatene_uroky'], + }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 6, + r035_zaplatene_uroky: '123,45', + }, + expected: [], + }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 6, + r035_zaplatene_uroky: '123.45', + }, + expected: [], + }, + { + input: { + r035_uplatnuje_uroky: true, + hypoteka_step: 6, + r035_zaplatene_uroky: '123,45a', + }, + expected: ['r035_zaplatene_uroky'], + } ]) }) }) diff --git a/__tests__/routes.test.ts b/__tests__/routes.test.ts index 46b3dac9..a64f7f15 100644 --- a/__tests__/routes.test.ts +++ b/__tests__/routes.test.ts @@ -18,6 +18,7 @@ describe('routes', () => { '/partner', '/deti', '/dochodok', + '/uroky', '/dve-percenta', '/osobne-udaje', '/suhrn', @@ -36,6 +37,7 @@ describe('routes', () => { '/partner', '/deti', '/dochodok', + '/uroky', '/dve-percenta', '/osobne-udaje', '/suhrn', @@ -56,6 +58,7 @@ describe('routes', () => { '/partner', '/deti', '/dochodok', + '/uroky', '/dve-percenta', '/osobne-udaje', '/suhrn', @@ -77,6 +80,7 @@ describe('routes', () => { '/partner', '/deti', '/dochodok', + '/uroky', '/dve-percenta', '/osobne-udaje', '/suhrn', diff --git a/__tests__/testCases/bugReport1Input.ts b/__tests__/testCases/bugReport1Input.ts index 0a65df15..60ef8883 100644 --- a/__tests__/testCases/bugReport1Input.ts +++ b/__tests__/testCases/bugReport1Input.ts @@ -50,8 +50,6 @@ export const bugReport1Input: E2eTestUserInput = { ], platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '', - r037_pocetMesiacov: '', - r037_zaplatene_uroky: '', expectNgoDonationValue: false, r142_ico: '', r142_obchMeno: '', diff --git a/__tests__/testCases/bugReport2aInput.ts b/__tests__/testCases/bugReport2aInput.ts index bf9334ea..2f17a568 100644 --- a/__tests__/testCases/bugReport2aInput.ts +++ b/__tests__/testCases/bugReport2aInput.ts @@ -45,8 +45,6 @@ export const bugReport2aInput: E2eTestUserInput = { ], platil_prispevky_na_dochodok: true, zaplatene_prispevky_na_dochodok: '100', - r037_pocetMesiacov: '', - r037_zaplatene_uroky: '', expectNgoDonationValue: true, XIIoddiel_uplatnujem2percenta: false, r142_ico: '', diff --git a/__tests__/testCases/bugReport2bInput.ts b/__tests__/testCases/bugReport2bInput.ts index f82c5751..da3fa07f 100644 --- a/__tests__/testCases/bugReport2bInput.ts +++ b/__tests__/testCases/bugReport2bInput.ts @@ -35,8 +35,6 @@ export const bugReport2bInput: E2eTestUserInput = { children: [], platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', - r037_pocetMesiacov: '', - r037_zaplatene_uroky: '', expectNgoDonationValue: true, XIIoddiel_uplatnujem2percenta: false, r142_ico: '', diff --git a/__tests__/testCases/bugReport3Input.ts b/__tests__/testCases/bugReport3Input.ts index 9722cae2..3132ee48 100644 --- a/__tests__/testCases/bugReport3Input.ts +++ b/__tests__/testCases/bugReport3Input.ts @@ -52,8 +52,6 @@ export const bugReport3Input: E2eTestUserInput = { ], platil_prispevky_na_dochodok: true, zaplatene_prispevky_na_dochodok: '100', - r037_pocetMesiacov: '', - r037_zaplatene_uroky: '', expectNgoDonationValue: true, XIIoddiel_uplatnujem2percenta: false, r142_ico: '', diff --git a/__tests__/testCases/bugReport5Input.ts b/__tests__/testCases/bugReport5Input.ts index 8726c03f..fe59666d 100644 --- a/__tests__/testCases/bugReport5Input.ts +++ b/__tests__/testCases/bugReport5Input.ts @@ -42,8 +42,6 @@ export const bugReport5Input: E2eTestUserInput = { ], "platil_prispevky_na_dochodok": true, "zaplatene_prispevky_na_dochodok": "180", - "r037_pocetMesiacov": "", - "r037_zaplatene_uroky": "", "expectNgoDonationValue": true, "XIIoddiel_uplatnujem2percenta": true, "splnam3per": false, diff --git a/__tests__/testCases/bugReport6Input.ts b/__tests__/testCases/bugReport6Input.ts index 0447a3a8..aa315fb1 100644 --- a/__tests__/testCases/bugReport6Input.ts +++ b/__tests__/testCases/bugReport6Input.ts @@ -52,8 +52,7 @@ export const bugReport6Input: E2eTestUserInput = { ], "platil_prispevky_na_dochodok": false, "zaplatene_prispevky_na_dochodok": "", - "r037_pocetMesiacov": "", - "r037_zaplatene_uroky": "", + "splnam3per": false, "r142_ico": "", "r142_obchMeno": "", diff --git a/__tests__/testCases/case202201Input.ts b/__tests__/testCases/case202201Input.ts index 0fc98ce0..4f8e4218 100644 --- a/__tests__/testCases/case202201Input.ts +++ b/__tests__/testCases/case202201Input.ts @@ -26,11 +26,6 @@ export const case202201Input: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '1084.26', employed: true, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', diff --git a/__tests__/testCases/case202202aInput.ts b/__tests__/testCases/case202202aInput.ts index 83af842b..23251629 100644 --- a/__tests__/testCases/case202202aInput.ts +++ b/__tests__/testCases/case202202aInput.ts @@ -26,11 +26,6 @@ export const case202202aInput: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '0', employed: false, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', diff --git a/__tests__/testCases/case202202bInput.ts b/__tests__/testCases/case202202bInput.ts index 7dd7a776..4f033c7c 100644 --- a/__tests__/testCases/case202202bInput.ts +++ b/__tests__/testCases/case202202bInput.ts @@ -26,11 +26,6 @@ export const case202202bInput: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '0', employed: false, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', diff --git a/__tests__/testCases/case202202cInput.ts b/__tests__/testCases/case202202cInput.ts index 44ad298d..2c524c72 100644 --- a/__tests__/testCases/case202202cInput.ts +++ b/__tests__/testCases/case202202cInput.ts @@ -26,11 +26,6 @@ export const case202202cInput: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '0', employed: false, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', diff --git a/__tests__/testCases/case202202dInput.ts b/__tests__/testCases/case202202dInput.ts index 6b198c47..a9d6d7fa 100644 --- a/__tests__/testCases/case202202dInput.ts +++ b/__tests__/testCases/case202202dInput.ts @@ -26,11 +26,6 @@ export const case202202dInput: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '0', employed: false, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', diff --git a/__tests__/testCases/case202203Input.ts b/__tests__/testCases/case202203Input.ts index a3a4bfcc..bdbb6fbe 100644 --- a/__tests__/testCases/case202203Input.ts +++ b/__tests__/testCases/case202203Input.ts @@ -26,11 +26,6 @@ export const case202203Input: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '0', employed: false, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', diff --git a/__tests__/testCases/case202204Input.ts b/__tests__/testCases/case202204Input.ts index 7a5534a0..dae031ea 100644 --- a/__tests__/testCases/case202204Input.ts +++ b/__tests__/testCases/case202204Input.ts @@ -26,11 +26,6 @@ export const case202204Input: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '848.52', employed: true, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', diff --git a/__tests__/testCases/case202205Input.ts b/__tests__/testCases/case202205Input.ts index 0e2a74f5..fccf6744 100644 --- a/__tests__/testCases/case202205Input.ts +++ b/__tests__/testCases/case202205Input.ts @@ -26,11 +26,6 @@ export const case202205Input: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '0', employed: false, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: false, zaplatene_prispevky_na_dochodok: '0', diff --git a/__tests__/testCases/completeDecimalInput.ts b/__tests__/testCases/completeDecimalInput.ts index 5524e0f0..2da81fbd 100644 --- a/__tests__/testCases/completeDecimalInput.ts +++ b/__tests__/testCases/completeDecimalInput.ts @@ -25,11 +25,6 @@ export const completeDecimalInput: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '50.75', employed: true, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200,32', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: true, zaplatene_prispevky_na_dochodok: '170,32', diff --git a/__tests__/testCases/completeInput.ts b/__tests__/testCases/completeInput.ts index 3768aa6b..90976990 100644 --- a/__tests__/testCases/completeInput.ts +++ b/__tests__/testCases/completeInput.ts @@ -26,11 +26,6 @@ export const completeInput: E2eTestUserInput = { udajeODanovomBonuseNaDieta: '50', employed: true, - /** SECTION Mortgage */ - r037_uplatnuje_uroky: true, - r037_zaplatene_uroky: '200', - r037_pocetMesiacov: '12', - /** SECTION Pension */ platil_prispevky_na_dochodok: true, zaplatene_prispevky_na_dochodok: '180', diff --git a/__tests__/testCases/uroky202301aInput.ts b/__tests__/testCases/uroky202301aInput.ts new file mode 100644 index 00000000..48abadef --- /dev/null +++ b/__tests__/testCases/uroky202301aInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202301Input } from './case202301Input' + +export const uroky202301aInput: E2eTestUserInput = { + ...case202301Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - 3).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - 3).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202301bInput.ts b/__tests__/testCases/uroky202301bInput.ts new file mode 100644 index 00000000..bddaa193 --- /dev/null +++ b/__tests__/testCases/uroky202301bInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR, UROKY_POCET_ROKOV } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202301Input } from './case202301Input' + +export const uroky202301bInput: E2eTestUserInput = { + ...case202301Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202301cInput.ts b/__tests__/testCases/uroky202301cInput.ts new file mode 100644 index 00000000..965addb4 --- /dev/null +++ b/__tests__/testCases/uroky202301cInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202301Input } from './case202301Input' + +export const uroky202301cInput: E2eTestUserInput = { + ...case202301Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: TAX_YEAR.toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: TAX_YEAR.toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202302aInput.ts b/__tests__/testCases/uroky202302aInput.ts new file mode 100644 index 00000000..2a6dc9e1 --- /dev/null +++ b/__tests__/testCases/uroky202302aInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202302Input } from './case202302Input' + +export const uroky202302aInput: E2eTestUserInput = { + ...case202302Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - 3).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - 3).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202302bInput.ts b/__tests__/testCases/uroky202302bInput.ts new file mode 100644 index 00000000..7b09df6e --- /dev/null +++ b/__tests__/testCases/uroky202302bInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR, UROKY_POCET_ROKOV } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202302Input } from './case202302Input' + +export const uroky202302bInput: E2eTestUserInput = { + ...case202302Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202302cInput.ts b/__tests__/testCases/uroky202302cInput.ts new file mode 100644 index 00000000..d12b99ba --- /dev/null +++ b/__tests__/testCases/uroky202302cInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202302Input } from './case202302Input' + +export const uroky202302cInput: E2eTestUserInput = { + ...case202302Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: TAX_YEAR.toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: TAX_YEAR.toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202303aInput.ts b/__tests__/testCases/uroky202303aInput.ts new file mode 100644 index 00000000..d4d94583 --- /dev/null +++ b/__tests__/testCases/uroky202303aInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202303Input } from './case202303Input' + +export const uroky202303aInput: E2eTestUserInput = { + ...case202303Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - 3).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - 3).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202303bInput.ts b/__tests__/testCases/uroky202303bInput.ts new file mode 100644 index 00000000..7f0a3d2b --- /dev/null +++ b/__tests__/testCases/uroky202303bInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR, UROKY_POCET_ROKOV } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202303Input } from './case202303Input' + +export const uroky202303bInput: E2eTestUserInput = { + ...case202303Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202303cInput.ts b/__tests__/testCases/uroky202303cInput.ts new file mode 100644 index 00000000..101c2781 --- /dev/null +++ b/__tests__/testCases/uroky202303cInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202303Input } from './case202303Input' + +export const uroky202303cInput: E2eTestUserInput = { + ...case202303Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: TAX_YEAR.toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: TAX_YEAR.toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202304aInput.ts b/__tests__/testCases/uroky202304aInput.ts new file mode 100644 index 00000000..31caed72 --- /dev/null +++ b/__tests__/testCases/uroky202304aInput.ts @@ -0,0 +1,16 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202304Input } from './case202304Input' + +export const uroky202304aInput: E2eTestUserInput = { + ...case202304Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - 3).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - 3).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', + percent2: '193,04' +} diff --git a/__tests__/testCases/uroky202304bInput.ts b/__tests__/testCases/uroky202304bInput.ts new file mode 100644 index 00000000..60b50656 --- /dev/null +++ b/__tests__/testCases/uroky202304bInput.ts @@ -0,0 +1,16 @@ +import { TAX_YEAR, UROKY_POCET_ROKOV } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202304Input } from './case202304Input' + +export const uroky202304bInput: E2eTestUserInput = { + ...case202304Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', + percent2: '196,37' +} diff --git a/__tests__/testCases/uroky202304cInput.ts b/__tests__/testCases/uroky202304cInput.ts new file mode 100644 index 00000000..e11d81cf --- /dev/null +++ b/__tests__/testCases/uroky202304cInput.ts @@ -0,0 +1,16 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202304Input } from './case202304Input' + +export const uroky202304cInput: E2eTestUserInput = { + ...case202304Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: TAX_YEAR.toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: TAX_YEAR.toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', + percent2: '197,71' +} diff --git a/__tests__/testCases/uroky202305aInput.ts b/__tests__/testCases/uroky202305aInput.ts new file mode 100644 index 00000000..ea572952 --- /dev/null +++ b/__tests__/testCases/uroky202305aInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202305Input } from './case202305Input' + +export const uroky202305aInput: E2eTestUserInput = { + ...case202305Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - 3).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - 3).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202305bInput.ts b/__tests__/testCases/uroky202305bInput.ts new file mode 100644 index 00000000..30d89e23 --- /dev/null +++ b/__tests__/testCases/uroky202305bInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR, UROKY_POCET_ROKOV } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202305Input } from './case202305Input' + +export const uroky202305bInput: E2eTestUserInput = { + ...case202305Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: (TAX_YEAR - UROKY_POCET_ROKOV).toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202305cInput.ts b/__tests__/testCases/uroky202305cInput.ts new file mode 100644 index 00000000..212566bb --- /dev/null +++ b/__tests__/testCases/uroky202305cInput.ts @@ -0,0 +1,15 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202305Input } from './case202305Input' + +export const uroky202305cInput: E2eTestUserInput = { + ...case202305Input, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: TAX_YEAR.toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: TAX_YEAR.toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '987.65', +} diff --git a/__tests__/testCases/uroky202306Input.ts b/__tests__/testCases/uroky202306Input.ts new file mode 100644 index 00000000..1c97c82f --- /dev/null +++ b/__tests__/testCases/uroky202306Input.ts @@ -0,0 +1,19 @@ +import { TAX_YEAR } from '../../src/lib/calculation' +import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' +import { case202301Input } from './case202301Input' + +export const uroky202306Input: E2eTestUserInput = { + ...case202301Input, + t1r10_prijmy: '43351.93', + partner_bonus_na_deti: false, + r035_uplatnuje_uroky: true, + uroky_rok_uzatvorenia: TAX_YEAR.toString(), + uroky_zaciatok_urocenia_den: '21', + uroky_zaciatok_urocenia_mesiac: '8', + uroky_zaciatok_urocenia_rok: TAX_YEAR.toString(), + uroky_dalsi_dlznik: true, + uroky_pocet_dlznikov: '2', + r035_zaplatene_uroky: '347.77', + expectNgoDonationValue: true, + percent2: '4,40' +} diff --git a/cypress/e2e/executeCase.ts b/cypress/e2e/executeCase.ts index 1bcd3371..c1920bb6 100644 --- a/cypress/e2e/executeCase.ts +++ b/cypress/e2e/executeCase.ts @@ -15,7 +15,6 @@ import { postponeHomeRoute, } from '../../src/lib/routes' import { PostponeUserInput } from '../../src/types/PostponeUserInput' -import Decimal from 'decimal.js' import path from 'path' import { E2eTestUserInput } from '../../src/types/E2eTestUserInput' @@ -194,19 +193,48 @@ const executeTestCase = (testCase: string) => { next() - // TODO Reanable with mortgage feature - // /** SECTION Hypoteka */ - // assertUrl('/hypoteka') + /** SECTION Hypoteka */ + assertUrl('/uroky') - // if (input.r037_uplatnuje_uroky) { - // getInput('r037_uplatnuje_uroky', '-yes').click() - // typeToInput('r037_zaplatene_uroky', input) - // typeToInput('r037_pocetMesiacov', input) - // } else { - // getInput('r037_uplatnuje_uroky', '-no').click() - // } + if (input.r035_uplatnuje_uroky) { + getInput('r035_uplatnuje_uroky', '-yes').click() - // next() + next() + + getInput('uroky_dalsi_uver_uplatnuje', '-no').click() + + next() + + typeToInput('uroky_rok_uzatvorenia', input) + typeToInput('uroky_zaciatok_urocenia_den', input) + typeToInput('uroky_zaciatok_urocenia_mesiac', input) + typeToInput('uroky_zaciatok_urocenia_rok', input) + + next() + + if (input.uroky_dalsi_dlznik) { + getInput('uroky_dalsi_dlznik', '-yes').click() + typeToInput('uroky_pocet_dlznikov', input) + } else { + getInput('uroky_dalsi_dlznik', '-no').click() + } + + next() + + getInput('uroky_splnam_vek_kriteria', '-yes').click() + + next() + + getInput('uroky_splnam_prijem', '-yes').click() + + next() + + typeToInput('r035_zaplatene_uroky', input) + } else { + getInput('r035_uplatnuje_uroky', '-no').click() + } + + next() /** SECTION Two percent */ assertUrl('/dve-percenta') @@ -295,6 +323,23 @@ const executeTestCase = (testCase: string) => { next() } + if (taxForm.mozeZiadatVratitDanovyBonusUroky) { + /** SECTION IBAN */ + assertUrl('/iban') + + cy.contains('Žiadam o vyplatenie daňového bonusu na zaplatené úroky') + cy.get('[data-test=ineligible-message]').should('not.exist') + + if (input.ziadamVratitDanovyBonusUroky) { + getInput('ziadamVratitDanovyBonusUroky', '-yes').click() + typeToInput('iban', input) + } else { + getInput('ziadamVratitDanovyBonusUroky', '-no').click() + } + + next() + } + if (taxForm.mozeZiadatVratitDanovyPreplatok) { /** SECTION IBAN */ assertUrl('/iban') diff --git a/cypress/e2e/pagePercent.spec.ts b/cypress/e2e/pagePercent.spec.ts index 7aa16b2e..8d6c0658 100644 --- a/cypress/e2e/pagePercent.spec.ts +++ b/cypress/e2e/pagePercent.spec.ts @@ -132,6 +132,11 @@ describe('twoPercent page', () => { next() + /* SECTION Uroky */ + getInput('r035_uplatnuje_uroky', '-no').click() + + next() + // Shows error, when presses next without interaction next() getError().should('have.length', 1) @@ -248,6 +253,11 @@ describe('twoPercent page', () => { next() + /* SECTION Uroky */ + getInput('r035_uplatnuje_uroky', '-no').click() + + next() + // When presses yes, additional fields appear cy.get('[data-test=XIIoddiel_uplatnujem2percenta-input-yes]').click() @@ -358,6 +368,11 @@ describe('twoPercent page', () => { next() + /* SECTION Uroky */ + getInput('r035_uplatnuje_uroky', '-no').click() + + next() + cy.get('[data-test=XIIoddiel_uplatnujem2percenta-input-no]').click() next() getError().should('have.length', 0) @@ -459,6 +474,11 @@ describe('twoPercent page', () => { next() + /* SECTION Uroky */ + getInput('r035_uplatnuje_uroky', '-no').click() + + next() + cy.get('[data-test=prefill-slovensko-digital]').click() getInput('r142_obchMeno').should('contain.value', 'Slovensko.Digital') diff --git a/cypress/e2e/pages.spec.ts b/cypress/e2e/pages.spec.ts index b68d484b..a512766b 100644 --- a/cypress/e2e/pages.spec.ts +++ b/cypress/e2e/pages.spec.ts @@ -627,7 +627,7 @@ describe('Pension page', () => { cy.get('[data-test=platil_prispevky_na_dochodok-input-no]').click() next() next() - assertUrl('/osobne-udaje') + assertUrl('/uroky') // Go back to our page cy.visit('/dochodok') @@ -643,7 +643,7 @@ describe('Pension page', () => { next() next() - assertUrl('/osobne-udaje') + assertUrl('/uroky') }) }) @@ -808,7 +808,7 @@ describe('Summary page', () => { '/deti', '/deti', '/dochodok', - // '/hypoteka', + '/uroky', '/osobne-udaje', ].forEach((link: Route, index) => { it(`has working edit link to ${link}`, () => { diff --git a/cypress/e2e/uroky.spec.ts b/cypress/e2e/uroky.spec.ts new file mode 100644 index 00000000..1a6ab327 --- /dev/null +++ b/cypress/e2e/uroky.spec.ts @@ -0,0 +1,22 @@ +import { executeAllTestCases } from './executeCase' + +describe('Uroky', () => { + executeAllTestCases([ + 'uroky202301a', + 'uroky202301b', + 'uroky202301c', + 'uroky202302a', + 'uroky202302b', + 'uroky202302c', + 'uroky202303a', + 'uroky202303b', + 'uroky202303c', + 'uroky202304a', + 'uroky202304b', + 'uroky202304c', + 'uroky202305a', + 'uroky202305b', + 'uroky202305c', + 'uroky202306', + ]) +}) diff --git a/src/components/UrokyBonusForm.tsx b/src/components/UrokyBonusForm.tsx new file mode 100644 index 00000000..30176f2c --- /dev/null +++ b/src/components/UrokyBonusForm.tsx @@ -0,0 +1,91 @@ +import { UrokyUserInput } from '../types/PageUserInputs' +import React, { useEffect, useRef } from 'react' +import { FormikProps } from 'formik' +import { + DalsiDlzniciQuestion, + ApplyForBonusQuestion, + ZaciatokUveruQuestion, + ZaplateneUrokyQuestion, + NotEligible, + PreviousButton, + SubmitButton, + DalsiUverQuestion, + VekQuestion, + PrijemQuestion, +} from './UrokyBonusFormSteps' +import { validateUrokyBonusForm } from '../lib/validateUrokyBonusForm' + +const scrollToElement = (element, smooth = true) => { + if (element && element.current) { + element.current.scrollIntoView({ + behavior: smooth ? 'smooth' : 'auto', + block: 'center', + }) + } +} + +export interface UrokyBonusFormProps extends FormikProps { + step: number + setStep: (step: number) => void +} + +export const UrokyBonusForm = (props: UrokyBonusFormProps) => { + const { values, setStep, step } = props + const questionElements = [ + useRef(), + useRef(), + useRef(), + useRef(), + useRef(), + useRef(), + useRef(), + ] + + useEffect(() => { + setTimeout(() => { + scrollToElement(questionElements[step]) + }, 25) + }, [step, questionElements]) + + const previousStep = () => { + setStep(step - 1) + } + + const questions: React.FC[] = [ApplyForBonusQuestion] + + const addQuestionForStep = (currentStep, NextQuestion) => { + if (step >= currentStep) { + if (validateUrokyBonusForm(values, currentStep)) { + questions.push(NextQuestion) + } else { + questions.push(NotEligible) + } + } + } + + addQuestionForStep(1, DalsiUverQuestion) + addQuestionForStep(2, ZaciatokUveruQuestion) + addQuestionForStep(3, DalsiDlzniciQuestion) + addQuestionForStep(4, VekQuestion) + addQuestionForStep(5, PrijemQuestion) + addQuestionForStep(6, ZaplateneUrokyQuestion) + + return ( + <> + {questions.map((Question, index) => { + const isLast = index === step + + return ( +
+ +
+ ) + })} + {step > 0 && } + + ) +} diff --git a/src/components/UrokyBonusFormSteps.tsx b/src/components/UrokyBonusFormSteps.tsx new file mode 100644 index 00000000..384ec8df --- /dev/null +++ b/src/components/UrokyBonusFormSteps.tsx @@ -0,0 +1,299 @@ +import React from 'react' +import { BooleanRadio, Checkbox, Input } from './FormComponents' +import { formatCurrency, formatRodneCislo } from '../lib/utils' +import { PartnerBonusFormProps } from './PartnerBonusForm' +import { Details } from './Details' +import { TAX_YEAR } from '../lib/calculation' +import Fieldset from './fieldset/Fieldset' +import RadioGroup from './radio/RadioGroup' +import Radio from './radio/Radio' +import RadioConditional from './radio/RadioConditional' +import Decimal from 'decimal.js' +import { Warning } from './Warning' + +export const ApplyForBonusQuestion = ({ disabled }) => ( + <> + +
+ <> +

+ Daňový bonus na zapletené úroky si môžete uplatniť na úver ktorý +

+
    +
  • má dobu splatnosti najmenej 5 rokov a najviac 30 rokov
  • +
  • je zabezpečený záložným právom k tuzemskej nehnuteľnosti
  • +
+ +
+ +) + +export const ZaplateneUrokyQuestion = ({ disabled }) => ( + <> + + + Potvrdenie vydané veriteľom (bankou) je potrebné priložiť ako prílohu k daňovému priznaniu. + + +) + + +export const ZaciatokUveruQuestion = ({ disabled }) => ( +
+ +

+ Ak si chcete uplatniť daňový bonus na zaplatené úroky z úveru na bývanie uveďte: +

+
+

+ Daňovník si môže uplatniť daňový bonus na zaplatené úroky počas piatich + bezprostredne po sebe nasledujúcich rokov počnúc mesiacom, + v ktorom začalo úročenie úveru na bývanie. +

+ + +
+
+
+ Zadajte datum začatia úročenia úveru napríklad +
+ 27 8 {TAX_YEAR - 3} +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+) + +export const DalsiDlzniciQuestion = ({ values, errors, setFieldValue, disabled }) => ( +
+ { + debugger + setFieldValue('uroky_dalsi_dlznik', value === 'true') + }}> + + + + + + + +
+) + +export const DalsiUverQuestion = ({ disabled }) => ( + +) + +export const VekQuestion = ({ disabled, values: { uroky_dalsi_dlznik } }) => ( + +) + +const maxPrijem = ({uroky_rok_uzatvorenia: rok, uroky_pocet_dlznikov, uroky_dalsi_dlznik}): Decimal => { + const pocet_dlznikov = uroky_dalsi_dlznik ? new Decimal(parseInt(uroky_pocet_dlznikov)) : new Decimal(1) + switch (rok) { + case '2018': + return new Decimal(1240.20).mul(pocet_dlznikov) + case '2019': + return new Decimal(1316.90).mul(pocet_dlznikov) + case '2020': + return new Decimal(1419.60).mul(pocet_dlznikov) + case '2021': + return new Decimal(1472.90).mul(pocet_dlznikov) + case '2022': + return new Decimal(1574.30).mul(pocet_dlznikov) + case '2023': + return new Decimal(1695.20).mul(pocet_dlznikov) + default: + return new Decimal(0) + } +} + +export const PrijemQuestion = ({ disabled, values: { uroky_dalsi_dlznik, uroky_rok_uzatvorenia, uroky_pocet_dlznikov } }) => { + const prijem = formatCurrency(maxPrijem({uroky_rok_uzatvorenia, uroky_pocet_dlznikov, uroky_dalsi_dlznik}).toNumber()) + + return ( + + ) +} + +export const ConditionsQuestion = ({ disabled }) => ( +
+ +

+ Spĺňa vaša manželka / manžel aspoň jednu z podmienok? +

+
+ + + + + + +
+) + +export const NotEligible = () => ( +
+

+ Nemáte nárok na uplatnenie +

+

Nespĺňate podmienky pre uplatnenie daňového bonusu na zaplatené úroky.

+
+) + +export const EligiblePartnerForm = ({ + values, + setFieldValue, +}: PartnerBonusFormProps) => ( + <> +

+ Vybrané údaje o manželke / manželovi +

+ + { + const pscValue = formatRodneCislo( + event.currentTarget.value, + values.r031_rodne_cislo, + ) + setFieldValue('r031_rodne_cislo', pscValue) + }} + /> + + + +) + +export const PreviousButton = ({ onClick }) => ( + +) + +export const SubmitButton = () => ( + +) diff --git a/src/lib/calculation.ts b/src/lib/calculation.ts index 47ccbdcc..16347a7c 100644 --- a/src/lib/calculation.ts +++ b/src/lib/calculation.ts @@ -43,6 +43,7 @@ const ZVYHODNENIE_NA_PARTNERA = 14_862.228 export const TAX_YEAR = 2023 export const MIN_2_PERCENT_CALCULATED_DONATION = 3 export const MAX_CHILD_AGE_BONUS = 25 +export const UROKY_POCET_ROKOV = 5 export enum Months { January = 1, @@ -112,6 +113,13 @@ const mapPartnerChildBonus = (input: ChildrenUserInput) => { } } +export const zaciatok_urocenia_datum = (input: TaxFormUserInput) => { + const den = Number.parseInt(input.uroky_zaciatok_urocenia_den, 10) + const mesiac = Number.parseInt(input.uroky_zaciatok_urocenia_mesiac, 10) + const rok = Number.parseInt(input.uroky_zaciatok_urocenia_rok, 10) + return new Date(rok, mesiac - 1, den) +} + export function calculate(input: TaxFormUserInput): TaxForm { /** Combine default vaules with user input */ return { @@ -190,12 +198,26 @@ export function calculate(input: TaxFormUserInput): TaxForm { r034a: new Decimal(parseInputNumber(input?.r034a ?? '0')), - /** SECTION Mortgage NAMES ARE WRONG TODO*/ - // r037_uplatnuje_uroky: input?.r037_uplatnuje_uroky ?? false, - // r037_zaplatene_uroky: new Decimal( - // parseInputNumber(input?.r037_zaplatene_uroky ?? '0'), - // ), - // r037_pocetMesiacov: parseInputNumber(input?.r037_pocetMesiacov ?? '0'), + /** SECTION Mortgage **/ + r035_uplat_dan_bonus_zaplat_uroky: input?.r035_uplatnuje_uroky ?? false, + get r035_zaplatene_uroky() { + return new Decimal(parseInputNumber(input?.r035_zaplatene_uroky ?? '0')) + }, + get r035_pocet_mesiacov(){ + const yearDiff = TAX_YEAR - Number.parseInt(input.uroky_zaciatok_urocenia_rok, 10) + if (yearDiff === 0) { + // Uver zacal v roku za ktory sa podava DP + return POCET_MESIACOV - Number.parseInt(input.uroky_zaciatok_urocenia_mesiac, 10) + 1 + } else if (yearDiff === UROKY_POCET_ROKOV) { + // Narok na DB je 5 rokov od zaciatku urokov a teda toto je posledny rok + return Number.parseInt(input.uroky_zaciatok_urocenia_mesiac, 10) - 1 + } else if (yearDiff < UROKY_POCET_ROKOV && yearDiff > 0) { + return POCET_MESIACOV + } + }, + get r035_datum_zacatia_urocenia_uveru() { + return zaciatok_urocenia_datum(input) + }, /** SECTION Employment */ r036: new Decimal( @@ -426,7 +448,7 @@ export function calculate(input: TaxFormUserInput): TaxForm { get r116_dan() { return round(this.r090.plus(this.r105)) }, - get r116a(){ + get r116a() { if (this.partner_bonus_na_deti) { if (this.r034.pocetMesiacov === 12) { return this.r034a.plus(this.r038).plus(this.r045) @@ -487,7 +509,7 @@ export function calculate(input: TaxFormUserInput): TaxForm { } let zakladDane - if (this.partner_bonus_na_deti){ + if (this.partner_bonus_na_deti) { zakladDane = this.r116a } else { zakladDane = this.r038.plus(this.r045) @@ -513,7 +535,7 @@ export function calculate(input: TaxFormUserInput): TaxForm { danovyBonus = danovyBonus.plus(vysledok) } - return {danovyBonus, nevyuzityDanovyBonus} + return { danovyBonus, nevyuzityDanovyBonus } }, get r117() { return this.danovyBonusNaDieta.danovyBonus @@ -535,22 +557,40 @@ export function calculate(input: TaxFormUserInput): TaxForm { get r122() { return Decimal.max(this.r119.minus(this.r117), 0) }, + get r123() { + if (this.r035_uplat_dan_bonus_zaplat_uroky) { + let limit = new Decimal(400) + if (this.r035_pocet_mesiacov !== 12) { + const mesacne = round(limit.div(12)) + limit = mesacne.times(this.r035_pocet_mesiacov) + } + return Decimal.min(this.r035_zaplatene_uroky.times(0.5), limit) + } else { + return new Decimal(0) + } + }, + get r124() { + return Decimal.max(this.r118.minus(this.r123), 0) + }, + r125: new Decimal(0), + get r126() { + return Decimal.max(this.r123.minus(this.r125), 0) + }, get mozeZiadatVyplatitDanovyBonus() { return this.r121.gt(0) }, get mozeZiadatVratitDanovyPreplatok() { return this.r136_danovy_preplatok.gt(0) }, - get r124() { - return this.r118 - }, - /** TODO */ - // get r125() { - // return new Decimal(0) - // }, - // get r126() { - // return Decimal.max(this.r123.minus(this.r125), 0) - // }, + get mozeZiadatVratitDanovyBonusUroky() { + return this.r127.gt(0) + }, + get r127() { + return Decimal.max(this.r126.minus(this.r118), 0) + }, + r128: new Decimal(0), + r129: new Decimal(0), + r130: new Decimal(0), get r131() { return new Decimal(parseInputNumber(input?.uhrnPreddavkovNaDan ?? '0')) }, @@ -564,24 +604,32 @@ export function calculate(input: TaxFormUserInput): TaxForm { return new Decimal(0) }, get r135_dan_na_uhradu() { - const baseTax = - this.r116_dan.gt(17) || this.r117.gt(0) ? this.r116_dan : new Decimal(0) - - const tax = Decimal.max( - 0, - baseTax - .minus(this.r117) - .plus(this.r119) - .plus(this.r121) - .minus(this.r131) - .minus(this.r133), - ) - return tax.gt(5) ? tax : new Decimal(0) - // 'r. 125': má byť výsledkom Max(0,r.105-r.106+r.108+r.110-r.112+r.114+r.116+r.117-r.118-r.119-r.120-r.121-r.122-r.123-r.124) ak platí, r.105>17.00 alebo r.105<=17.00 a zároveň je r.106>0 alebo r.112>0. - // Inak r.125=max(0,0–r.106+r.108+r.110-r.112+r.114+r.116+r.117-r.118-r.119-r.120-r.121-r.122-r.123-r.124). - // Ak daň na úhradu nepresiahne 5€, daň sa neplatí, v r.125 sa uvedie nula. + /* + Ak (r.116>17,00) alebo (r.116<=17,00 a zároveň je r.117>0 alebo r.123>0), potom + r.135=Max(0,r. 116 - r. 117 + r. 119 + r. 121 - r. 123 + r. 125 + r. 127 + r. 128 - r. 129 - r. 130 - r. 131 - r. 132 - r. 133 - r. 134). + Inak r.135=Max(0,0 - r. 117 + r. 119 + r. 121 - r. 123 + r. 125 + r. 127 + r. 128 - r. 129 - r. 130 - r. 131 - r. 132 - r. 133 - r. 134). + Ak daň na úhradu nepresiahne 5 €, daň sa neplatí. + */ + + const podmienka = this.r116_dan.gt(17) || (this.r116_dan.lte(17) && (this.r117.gt(0) || this.r123.gt(0))) + const base = podmienka ? this.r116_dan : new Decimal(0) + let tax = base + .minus(this.r117) + .plus(this.r119) + .plus(this.r121) + .minus(this.r123) + .plus(this.r125) + .plus(this.r127) + .plus(this.r128) + .minus(this.r129) + .minus(this.r130) + .minus(this.r131) + .minus(this.r132) + .minus(this.r133) + .minus(this.r134) + tax = Decimal.max(0, tax) - // vo vypocte chyba: +r.116+r.117-r.118-r.119-r.121-r.123-r.124 (asi ich netreba lebo sa nevyplnaju vo formulari, tj su rovne nula) + return tax.gt(5) ? tax : new Decimal(0) }, get r136_danovy_preplatok() { return Decimal.abs( @@ -637,6 +685,7 @@ export function calculate(input: TaxFormUserInput): TaxForm { /** SECTION Danovy bonus */ ziadamVyplatitDanovyBonus: input?.ziadamVyplatitDanovyBonus ?? false, ziadamVratitDanovyPreplatok: input?.ziadamVratitDanovyPreplatok ?? false, + ziadamVratitDanovyBonusUroky: input?.ziadamVratitDanovyBonusUroky ?? false, iban: input?.iban ? input?.iban.replace(/\s/g, '') : '', datum: input.datum, @@ -660,7 +709,9 @@ export const buildSummary = (form: TaxForm): Summary => { danSpolu: form.r116_dan, preddavkyNaDan: (form.r131.plus(form.r132).plus(form.r133).plus(form.r134)).negated(), danovyBonusNaDeti: form.r117.negated(), + danovyBonusNaUroky: form.r123.negated(), danovyBonusNaVyplatenie: form.r121, + danovyBonysNaVyplatenieUroky: form.r127, danovyPreplatokNaVyplatenie: form.r136_danovy_preplatok, danNaUhradu: form.r135_dan_na_uhradu, } @@ -674,8 +725,8 @@ const getRate = (month: Months, child: Child) => { ) const rate = age < 18 - ? new Decimal(CHILD_RATE_EIGHTEEN_AND_YOUNGER) - : new Decimal(CHILD_RATE_EIGHTEEN_AND_OLDER) + ? new Decimal(CHILD_RATE_EIGHTEEN_AND_YOUNGER) + : new Decimal(CHILD_RATE_EIGHTEEN_AND_OLDER) if ( month === Months.January && diff --git a/src/lib/initialValues.ts b/src/lib/initialValues.ts index a1628db0..e0bf6ee5 100644 --- a/src/lib/initialValues.ts +++ b/src/lib/initialValues.ts @@ -5,7 +5,7 @@ import { EmployedUserInput, ChildrenUserInput, PensionUserInput, - MortgageUserInput, + UrokyUserInput, TwoPercentUserInput, TaxBonusUserInput, } from '../types/PageUserInputs' @@ -81,10 +81,10 @@ export const pensionInitialValues: PensionUserInput = { zaplatene_prispevky_na_dochodok: '', } -export const mortgageInitialValues: MortgageUserInput = { - r037_pocetMesiacov: '', - r037_zaplatene_uroky: '', - r037_uplatnuje_uroky: undefined, +export const urokyInitialValues: UrokyUserInput = { + r035_zaplatene_uroky: '', + r035_uplatnuje_uroky: undefined, + hypoteka_step: 0, } export const twoPercentInitialValues: TwoPercentUserInput = { @@ -107,7 +107,7 @@ export const initTaxFormUserInputValues: TaxFormUserInput = { ...employmentUserInputInitialValues, ...childrenUserInputInitialValues, ...pensionInitialValues, - ...mortgageInitialValues, + ...urokyInitialValues, ...twoPercentInitialValues, ...taxBonusInitialInput, ...{ datum: '' }, diff --git a/src/lib/routes.ts b/src/lib/routes.ts index 57410aa2..42f8925d 100644 --- a/src/lib/routes.ts +++ b/src/lib/routes.ts @@ -17,7 +17,7 @@ export type Route = | '/partner' | '/deti' | '/dochodok' - | '/hypoteka' + | '/uroky' | '/dve-percenta' | '/osobne-udaje' | '/suhrn' @@ -29,7 +29,8 @@ export const getOrderedRoutes = (taxForm: TaxForm): ReadonlyArray => { const getIbanRoute = (): Route[] => { const isIbanRequired = taxForm.mozeZiadatVyplatitDanovyBonus || - taxForm.mozeZiadatVratitDanovyPreplatok + taxForm.mozeZiadatVratitDanovyPreplatok || + taxForm.mozeZiadatVratitDanovyBonusUroky return isIbanRequired ? ['/iban'] : [] } @@ -40,6 +41,7 @@ export const getOrderedRoutes = (taxForm: TaxForm): ReadonlyArray => { '/partner', '/deti', '/dochodok', + '/uroky', '/dve-percenta', '/osobne-udaje', '/suhrn', diff --git a/src/lib/validateUrokyBonusForm.ts b/src/lib/validateUrokyBonusForm.ts new file mode 100644 index 00000000..498e7eda --- /dev/null +++ b/src/lib/validateUrokyBonusForm.ts @@ -0,0 +1,33 @@ +import { UrokyUserInput } from '../types/PageUserInputs' +import { TAX_YEAR, UROKY_POCET_ROKOV } from './calculation' + +export const validateUrokyBonusForm = ( + values: UrokyUserInput, + step = null, +): boolean => { + const step0 = true // first step is not validated + + const step1 = values.uroky_dalsi_uver_uplatnuje === false + + const den = Number.parseInt(values.uroky_zaciatok_urocenia_den, 10) + const mesiac = Number.parseInt(values.uroky_zaciatok_urocenia_mesiac, 10) + const rok = Number.parseInt(values.uroky_zaciatok_urocenia_rok, 10) + const zaciatok_urocenia = new Date(rok, mesiac - 1, den) + const limit_zaciatku = new Date(TAX_YEAR-UROKY_POCET_ROKOV, 0, 1) + + const step2 = zaciatok_urocenia >= limit_zaciatku + + const step3 = true + + const step4 = values.uroky_splnam_vek_kriteria === true + + const step5 = values.uroky_splnam_prijem === true + + const steps = [step0, step1, step2, step3, step4, step5] + + if (step !== null) { + return steps[step - 1] // return value for given step + } + + return steps.every((value) => value === true) // validate for all steps +} diff --git a/src/lib/xml/xmlConverter.ts b/src/lib/xml/xmlConverter.ts index 3d951c6e..deba25c2 100644 --- a/src/lib/xml/xmlConverter.ts +++ b/src/lib/xml/xmlConverter.ts @@ -3,7 +3,7 @@ import cloneDeep from 'lodash.clonedeep' import outputBasis from './outputBasis' import { TaxForm } from '../../types/TaxForm' import { OutputJson, Dieta } from '../../types/OutputJson' -import { boolToString, decimalToString, roundDecimal } from '../utils' +import { boolToString, decimalToString, formatDate, roundDecimal } from '../utils' export function convertToJson(taxForm: TaxForm): OutputJson { const form: OutputJson = cloneDeep(outputBasis) @@ -101,15 +101,15 @@ export function convertToJson(taxForm: TaxForm): OutputJson { } /** SECTION Mortgage */ - // if (taxForm.r037_uplatnuje_uroky) { - // form.dokument.telo.r37 = { - // uplatDanBonusZaplatUroky: boolToString(taxForm.r037_uplatnuje_uroky), - // zaplateneUroky: taxForm.r037_zaplatene_uroky.toFixed(2), - // pocetMesiacov: taxForm.r037_pocetMesiacov.toFixed(), - // } - // form.dokument.telo.r112 = taxForm.r123.toFixed(2) - // form.dokument.telo.r115 = taxForm.r126.toFixed(2) - // } + if (taxForm.r035_uplat_dan_bonus_zaplat_uroky) { + form.dokument.telo.r35 = { + uplatDanBonusZaplatUroky: boolToString(taxForm.r035_uplat_dan_bonus_zaplat_uroky), + zaplateneUroky: decimalToString(taxForm.r035_zaplatene_uroky), + pocetMesiacov: taxForm.r035_pocet_mesiacov.toString(), + datumZacatiaUroceniaUveru: formatDate(taxForm.r035_datum_zacatia_urocenia_uveru) + } + } + /** SECTION Employed */ if (taxForm.employed) { @@ -152,8 +152,10 @@ export function convertToJson(taxForm: TaxForm): OutputJson { form.dokument.telo.r120 = decimalToString(taxForm.r120) form.dokument.telo.r121 = decimalToString(taxForm.r121) form.dokument.telo.r122 = decimalToString(taxForm.r122) - + form.dokument.telo.r123 = decimalToString(taxForm.r123) form.dokument.telo.r124 = roundDecimal(taxForm.r124) + form.dokument.telo.r126 = decimalToString(taxForm.r126) + form.dokument.telo.r127 = decimalToString(taxForm.r127) form.dokument.telo.r131 = decimalToString(taxForm.r131) form.dokument.telo.r133 = decimalToString(taxForm.r133) @@ -180,13 +182,14 @@ export function convertToJson(taxForm: TaxForm): OutputJson { form.dokument.telo.r153 = taxForm.employed ? '5' : '4' - const maDanovBonus = + const maDanovyBonus = taxForm.mozeZiadatVyplatitDanovyBonus && taxForm.ziadamVyplatitDanovyBonus + const maDanovyBonusUroky = taxForm.mozeZiadatVratitDanovyBonusUroky && taxForm.ziadamVratitDanovyBonusUroky const maDanovyPreplatok = taxForm.mozeZiadatVratitDanovyPreplatok && taxForm.ziadamVratitDanovyPreplatok - if (maDanovBonus || maDanovyPreplatok) { + if (maDanovyBonus || maDanovyPreplatok || maDanovyBonusUroky) { form.dokument.telo.danovyPreplatokBonus.bankovyUcet.IBAN = taxForm.iban form.dokument.telo.danovyPreplatokBonus.datum = taxForm.datum form.dokument.telo.danovyPreplatokBonus.sposobPlatby.ucet = '1' @@ -197,6 +200,9 @@ export function convertToJson(taxForm: TaxForm): OutputJson { if (taxForm.ziadamVratitDanovyPreplatok) { form.dokument.telo.danovyPreplatokBonus.vratitDanPreplatok = '1' } + if (taxForm.ziadamVratitDanovyBonusUroky) { + form.dokument.telo.danovyPreplatokBonus.vyplatitDanovyBonusUroky = '1' + } } form.dokument.telo.datumVyhlasenia = taxForm.datum diff --git a/src/pages/hypoteka.tsx b/src/pages/hypoteka.tsx deleted file mode 100644 index 41637d78..00000000 --- a/src/pages/hypoteka.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react' -import Link from 'next/link' -import { Form } from 'formik' -import { BooleanRadio, FormWrapper, Input } from '../components/FormComponents' -import { FormErrors, MortgageUserInput } from '../types/PageUserInputs' -import { ErrorSummary } from '../components/ErrorSummary' -import { numberInputRegexp } from '../lib/utils' -import { Page } from '../components/Page' -import { mortgageInitialValues } from '../lib/initialValues' -import { TAX_YEAR } from '../lib/calculation' - -const Hypoteka: Page = ({ - setTaxFormUserInput, - taxFormUserInput, - router, - previousRoute, - nextRoute, -}) => { - return ( - <> - - Späť - - - initialValues={taxFormUserInput} - validate={validate} - onSubmit={(values) => { - const userInput = values.r037_uplatnuje_uroky - ? values - : { - ...mortgageInitialValues, - r037_uplatnuje_uroky: false, - } - setTaxFormUserInput(userInput) - router.push(nextRoute) - }} - > - {({ values, errors }) => ( -
- - {values.r037_uplatnuje_uroky && ( - <> - errors={errors} /> - - - - )} - - - )} - - - ) -} - -export const validate = (values: MortgageUserInput) => { - const errors: Partial> = {} - - if (typeof values.r037_uplatnuje_uroky === 'undefined') { - errors.r037_uplatnuje_uroky = 'Vyznačte odpoveď' - } - - if (values.r037_uplatnuje_uroky) { - if (!values.r037_zaplatene_uroky) { - errors.r037_zaplatene_uroky = 'Zadajte výšku zaplatených úrokov' - } else if (!values.r037_zaplatene_uroky.match(numberInputRegexp)) { - errors.r037_zaplatene_uroky = 'Zadajte zaplatené úroky vo formáte 123,45' - } - if (!values.r037_pocetMesiacov) { - errors.r037_pocetMesiacov = - 'Zadajte počet mesiacov, kedy ste platili úroky' - } else if ( - !values.r037_pocetMesiacov.match(/^\d+$/) || - Number.parseInt(values.r037_pocetMesiacov, 10) < 0 || - Number.parseInt(values.r037_pocetMesiacov, 10) > 12 - ) { - errors.r037_pocetMesiacov = 'Zadajte počet mesiacov - číslo od 0 do 12' - } - } - - return errors -} - -export default Hypoteka diff --git a/src/pages/iban.tsx b/src/pages/iban.tsx index 9a0d0f3e..ac61704b 100644 --- a/src/pages/iban.tsx +++ b/src/pages/iban.tsx @@ -24,7 +24,8 @@ const Iban: Page = ({ }) => { if ( !taxForm.mozeZiadatVyplatitDanovyBonus && - !taxForm.mozeZiadatVratitDanovyPreplatok + !taxForm.mozeZiadatVratitDanovyPreplatok && + !taxForm.mozeZiadatVratitDanovyBonusUroky ) { return ( <> @@ -51,13 +52,14 @@ const Iban: Page = ({ validate={makeValidate(taxForm)} onSubmit={(values) => { const userInput = - values.ziadamVyplatitDanovyBonus || values.ziadamVratitDanovyPreplatok + values.ziadamVyplatitDanovyBonus || values.ziadamVratitDanovyPreplatok || values.ziadamVratitDanovyBonusUroky ? values : { - ...taxBonusInitialInput, - ziadamVyplatitDanovyBonus: false, - ziadamVratitDanovyPreplatok: false, - } + ...taxBonusInitialInput, + ziadamVyplatitDanovyBonus: false, + ziadamVratitDanovyPreplatok: false, + ziadamVratitDanovyBonusUroky: false + } setTaxFormUserInput(userInput) router.push(nextRoute) }} @@ -82,24 +84,32 @@ const Iban: Page = ({ /> )} - {(values.ziadamVyplatitDanovyBonus || - values.ziadamVratitDanovyPreplatok) && ( - { - const iban = formatIban( - event.currentTarget.value, - values.iban, - ) - setFieldValue('iban', iban) - }} + {taxForm.mozeZiadatVratitDanovyBonusUroky && ( + )} + {(values.ziadamVyplatitDanovyBonus || + values.ziadamVratitDanovyPreplatok || + values.ziadamVratitDanovyBonusUroky) && ( + { + const iban = formatIban( + event.currentTarget.value, + values.iban, + ) + setFieldValue('iban', iban) + }} + /> + )} + @@ -131,9 +141,18 @@ export const makeValidate = 'Vyznačte odpoveď na daňový preplatok' } + if ( + taxForm.mozeZiadatVratitDanovyBonusUroky && + typeof values.ziadamVratitDanovyBonusUroky === 'undefined' + ) { + errors.ziadamVratitDanovyBonusUroky = + 'Vyznačte odpoveď na daňový bonus' + } + if ( values.ziadamVyplatitDanovyBonus || - values.ziadamVratitDanovyPreplatok + values.ziadamVratitDanovyPreplatok || + values.ziadamVratitDanovyBonusUroky ) { if (!values.iban || values.iban === '') { // Medzinárodné bankové číslo účtu (angl. International Bank Account Number, skr. IBAN) diff --git a/src/pages/suhrn.tsx b/src/pages/suhrn.tsx index ec2139cd..42d56014 100644 --- a/src/pages/suhrn.tsx +++ b/src/pages/suhrn.tsx @@ -1,13 +1,13 @@ import React from 'react' import Link from 'next/link' import { TaxFormUserInput } from '../types/TaxFormUserInput' -import { formatCurrency, parseInputNumber } from '../lib/utils' +import { formatCurrency, formatDate, parseInputNumber } from '../lib/utils' import styles from './suhrn.module.css' import classnames from 'classnames' import { Warning } from '../components/Warning' import { Page } from '../components/Page' import { BackLink } from '../components/BackLink' -import { TAX_YEAR, monthNumberToName, typPrijmuToName } from '../lib/calculation' +import { TAX_YEAR, monthNumberToName, typPrijmuToName, zaciatok_urocenia_datum } from '../lib/calculation' interface SummaryRow { title: string @@ -266,25 +266,25 @@ const Suhrn: Page = ({ : [{ title: 'Neplatil som' }] } /> - {/* */} + = ({ + taxFormUserInput, + setTaxFormUserInput, + router, + previousRoute, + nextRoute, +}) => { + return ( + <> + + Späť + + + initialValues={taxFormUserInput} + validate={validate} + onSubmit={(values, { setFieldValue }) => { + if ( + values.r035_uplatnuje_uroky === false || + validateUrokyBonusForm(values, values.hypoteka_step) === false || + values.hypoteka_step === 6 + ) { + const userInput = values.r035_uplatnuje_uroky + ? values + : { + ...urokyInitialValues, + r035_uplatnuje_uroky: false, + } + + if (!validateUrokyBonusForm(values, values.hypoteka_step)) { + userInput.r035_zaplatene_uroky = '' + } + + setTaxFormUserInput(userInput) + router.push(nextRoute) + } else { + setFieldValue('hypoteka_step', values.hypoteka_step + 1) + } + }} + > + {(props) => ( +
+ + props.setFieldValue('hypoteka_step', value)} + /> + + )} + + + ) +} + +export const validate = (values: UrokyUserInput) => { + const errors: Partial> = {} + if (typeof values.r035_uplatnuje_uroky === 'undefined') { + errors.r035_uplatnuje_uroky = 'Vyznačte odpoveď' + } + + if ( + values.hypoteka_step === 1 && + typeof values.uroky_dalsi_uver_uplatnuje === 'undefined' + ) { + errors.uroky_dalsi_uver_uplatnuje = 'Vyznačte odpoveď' + } else if (values.hypoteka_step === 2) { + if (typeof values.uroky_rok_uzatvorenia === 'undefined') { + errors.uroky_rok_uzatvorenia = 'Zadajte rok' + } else { + const rok = Number.parseInt(values.uroky_rok_uzatvorenia, 10) + if (rok > TAX_YEAR) { + errors.uroky_rok_uzatvorenia = 'Rok uzatvorenia úveru nemôže byť v budúcnosti' + } + } + + const ziaciatok_urocenia_den = Number.parseInt(values.uroky_zaciatok_urocenia_den, 10) + const zaciatok_urocenia_mesiac = Number.parseInt(values.uroky_zaciatok_urocenia_mesiac, 10) + const zaciatok_urocenia_rok = Number.parseInt(values.uroky_zaciatok_urocenia_rok, 10) + const zaciatok_urocenia = new Date(zaciatok_urocenia_rok, zaciatok_urocenia_mesiac - 1, ziaciatok_urocenia_den) + + if (zaciatok_urocenia.getDate() !== ziaciatok_urocenia_den) { + errors.uroky_zaciatok_urocenia_den = 'Zadajte deň v správnom tvare' + } + if ((zaciatok_urocenia.getMonth() + 1) !== zaciatok_urocenia_mesiac) { + errors.uroky_zaciatok_urocenia_mesiac = 'Zadajte mesiac v správnom tvare' + } + if (zaciatok_urocenia.getFullYear() !== zaciatok_urocenia_rok) { + errors.uroky_zaciatok_urocenia_rok = 'Zadajte rok v správnom tvare' + } + + if (zaciatok_urocenia.getFullYear() < TAX_YEAR - UROKY_POCET_ROKOV) { + errors.uroky_zaciatok_urocenia_rok = `Rok začiatku úročenia nemôže byť skôr ako ${TAX_YEAR - UROKY_POCET_ROKOV}` + } + + if (zaciatok_urocenia.getFullYear() > TAX_YEAR) { + errors.uroky_zaciatok_urocenia_rok = `Rok začiatku úročenia môže byť najviac ${TAX_YEAR}` + } + } else if (values.hypoteka_step === 3) { + if (typeof values.uroky_dalsi_dlznik === 'undefined') { + errors.uroky_dalsi_dlznik = 'Vyznačte odpoveď' + } else { + if (values.uroky_dalsi_dlznik) { + if (typeof values.uroky_pocet_dlznikov === 'undefined') { + errors.uroky_pocet_dlznikov = 'Zadajte počet dlžníkov' + } else if (!values.uroky_pocet_dlznikov.match(/^\d+$/)) { + errors.uroky_pocet_dlznikov = 'Zadajte počet dlžníkov vo formáte čísla napr. 5' + } else if (Number.parseInt(values.uroky_pocet_dlznikov, 10) < 2) { + errors.uroky_pocet_dlznikov = 'Počet dlžníkov musí byť aspoň 2' + } + } + } + } else if (values.hypoteka_step === 4) { + if (typeof values.uroky_splnam_vek_kriteria === 'undefined') { + errors.uroky_splnam_vek_kriteria = 'Vyznačte odpoveď' + } + } else if (values.hypoteka_step === 5) { + if (typeof values.uroky_splnam_prijem === 'undefined') { + errors.uroky_splnam_prijem = 'Vyznačte odpoveď' + } + } else if (values.hypoteka_step === 6) { + if (typeof values.r035_zaplatene_uroky === 'undefined') { + errors.r035_zaplatene_uroky = 'Zadajte zaplatené úroky' + } else if (!values.r035_zaplatene_uroky.match(numberInputRegexp)) { + errors.r035_zaplatene_uroky = 'Zadajte zaplatené úroky vo formáte 123,45' + } + } + + return errors +} + +export default Uroky diff --git a/src/pages/vysledky.tsx b/src/pages/vysledky.tsx index 274d75a2..e0306dca 100644 --- a/src/pages/vysledky.tsx +++ b/src/pages/vysledky.tsx @@ -105,13 +105,22 @@ const Vysledky: Page> = ({ title: 'Nárok na daňový bonus na deti', value: summary.danovyBonusNaDeti, key: 'danovyBonusNaDeti', - testId: 'r136_danovy_preplatok', + }, + { + title: 'Daňový bonus na zaplatené úroky', + value: summary.danovyBonusNaUroky, + key: 'danovyBonusNaUroky', }, { title: 'Daňový bonus na vyplatenie', value: summary.danovyBonusNaVyplatenie, key: 'danovyBonusNaVyplatenie', }, + { + title: 'Daňový bonus na vyplatenie úroky', + value: summary.danovyBonysNaVyplatenieUroky, + key: 'danovyBonysNaVyplatenieUroky' + }, { title: 'Daňový preplatok na vyplatenie', value: summary.danovyPreplatokNaVyplatenie, diff --git a/src/types/PageUserInputs.ts b/src/types/PageUserInputs.ts index d62f9365..a03180dc 100644 --- a/src/types/PageUserInputs.ts +++ b/src/types/PageUserInputs.ts @@ -81,9 +81,20 @@ export type PensionUserInput = Pick< 'platil_prispevky_na_dochodok' | 'zaplatene_prispevky_na_dochodok' > -export type MortgageUserInput = Pick< +export type UrokyUserInput = Pick< TaxFormUserInput, - 'r037_uplatnuje_uroky' | 'r037_zaplatene_uroky' | 'r037_pocetMesiacov' + 'r035_uplatnuje_uroky' + | 'r035_zaplatene_uroky' + | 'uroky_rok_uzatvorenia' + | 'uroky_zaciatok_urocenia_den' + | 'uroky_zaciatok_urocenia_mesiac' + | 'uroky_zaciatok_urocenia_rok' + | 'uroky_dalsi_dlznik' + | 'uroky_pocet_dlznikov' + | 'uroky_dalsi_uver_uplatnuje' + | 'uroky_splnam_vek_kriteria' + | 'uroky_splnam_prijem' + | 'hypoteka_step' > export type TwoPercentUserInput = Pick< @@ -97,7 +108,10 @@ export type TwoPercentUserInput = Pick< export type TaxBonusUserInput = Pick< TaxFormUserInput, - 'ziadamVyplatitDanovyBonus' | 'ziadamVratitDanovyPreplatok' | 'iban' + 'ziadamVyplatitDanovyBonus' + | 'ziadamVratitDanovyPreplatok' + | 'ziadamVratitDanovyBonusUroky' + | 'iban' > export type IncomeSourceCountryUserInput = Pick< diff --git a/src/types/Summary.ts b/src/types/Summary.ts index d3c58f01..112b5a75 100644 --- a/src/types/Summary.ts +++ b/src/types/Summary.ts @@ -10,7 +10,9 @@ export interface Summary { danSpolu: Decimal preddavkyNaDan: Decimal danovyBonusNaDeti: Decimal + danovyBonusNaUroky: Decimal danovyBonusNaVyplatenie: Decimal + danovyBonysNaVyplatenieUroky: Decimal danovyPreplatokNaVyplatenie: Decimal danNaUhradu: Decimal } diff --git a/src/types/TaxForm.ts b/src/types/TaxForm.ts index eee73b0b..2afc596a 100644 --- a/src/types/TaxForm.ts +++ b/src/types/TaxForm.ts @@ -77,9 +77,10 @@ export interface TaxForm { r032_partner_pocet_mesiacov?: number /** SECTION Mortage */ - // r037_uplatnuje_uroky?: boolean - // r037_zaplatene_uroky?: Decimal - // r037_pocetMesiacov?: number + r035_uplat_dan_bonus_zaplat_uroky?: boolean + r035_zaplatene_uroky?: Decimal + r035_pocet_mesiacov?: number + r035_datum_zacatia_urocenia_uveru?: Date /** SECTION Prijmy a poistenie */ /** VIs.Príjmy z tabuľky č. 1, stĺ. 1, r. 10 TODO asi zrkadlenie do VI.Príjmy z tabuľky č. 1, stĺ. 1, r. 2*/ @@ -187,16 +188,14 @@ export interface TaxForm { r122: Decimal - /** Riadok 112 vypĺňa daňovník, ktorý vyplnil IV. ODDIEL. Ak daňovník uplatňuje daňový bonus na zaplatené úroky podľa § 33a zákona, daňovým bonusom na zaplatené úroky podľa § 33a zákona je suma vo výške 50% zo zaplatených úrokov v príslušnom zdaňovacom období z riadku 37, najviac však do výšky 400 eur za rok. Ak obdobie úročenia úveru na bývanie počas ktorého má daňovník nárok na tento daňový bonus začalo v priebehu zdaňovacieho obdobia, uvádza sa v r. 112 suma zodpovedajúca pomernej časti daňového bonusu na zaplatené úroky z maximálnej sumy 400 eur pripadajúca na počet kalendárnych mesiacov, v ktorých vznikol nárok na jeho uplatnenie.*/ - // r123: Decimal - /** Daň (daňová povinnosť) znížená o daňový bonus a o daňový bonus na zaplatené - * úroky(r. 107 - r. 112) zrkadli r118*/ + r123: Decimal r124: Decimal - /** Daň na úhradu vrátane zamestnávateľom nesprávne vyplateného daňového bonusu - * podľa § 33 zákona33) r. 105 - r. 106 + r. 108 + r. 110 - r. 112 + r. 114 + - * r. 116 + r. 117 - r. 118 - r. 119 - r. 120 - r. 121 - r. 122 - r. 123 - r. - * 124 (+)*/ - + r125: Decimal + r126: Decimal + r127: Decimal + r128: Decimal + r129: Decimal + r130: Decimal /** zrazena dan zo zamestnania */ r131: Decimal r132: Decimal @@ -229,6 +228,8 @@ export interface TaxForm { ziadamVyplatitDanovyBonus: boolean mozeZiadatVratitDanovyPreplatok: boolean ziadamVratitDanovyPreplatok: boolean + mozeZiadatVratitDanovyBonusUroky: boolean + ziadamVratitDanovyBonusUroky: boolean iban: string /** Helper properties from input, that are not part of taxForm */ diff --git a/src/types/TaxFormUserInput.ts b/src/types/TaxFormUserInput.ts index c5d072f1..6aa24661 100644 --- a/src/types/TaxFormUserInput.ts +++ b/src/types/TaxFormUserInput.ts @@ -65,9 +65,18 @@ export interface TaxFormUserInput { partner_podmienky?: Record /** SECTION Mortage */ - r037_uplatnuje_uroky?: boolean - r037_zaplatene_uroky?: string - r037_pocetMesiacov?: string + r035_uplatnuje_uroky?: boolean + r035_zaplatene_uroky?: string + hypoteka_step?: number + uroky_rok_uzatvorenia?: string + uroky_zaciatok_urocenia_den?: string + uroky_zaciatok_urocenia_mesiac?: string + uroky_zaciatok_urocenia_rok?: string + uroky_dalsi_dlznik?: boolean + uroky_pocet_dlznikov?: string + uroky_dalsi_uver_uplatnuje?: boolean + uroky_splnam_vek_kriteria?: boolean + uroky_splnam_prijem?: boolean /** SECTION Prijmy a poistenie */ t1r10_prijmy: string @@ -104,6 +113,7 @@ export interface TaxFormUserInput { /** SECTION Danovy bonus */ ziadamVyplatitDanovyBonus?: boolean ziadamVratitDanovyPreplatok?: boolean + ziadamVratitDanovyBonusUroky?: boolean iban?: string /** Musi byt sucastou user inputu, aj ked sa generuje automaticky, inac by