@novha/calc-engines 7.0.0 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/all-commits.bundle +0 -0
- package/dist/capital-gains/brazil/BrazilCapitalGainsService.js +3 -0
- package/dist/capital-gains/brazil/BrazilCapitalGainsServiceImpl.js +56 -0
- package/dist/capital-gains/brazil/domain/types.js +3 -0
- package/dist/capital-gains/index.js +17 -2
- package/dist/capital-gains/india/IndiaCapitalGainsService.js +3 -0
- package/dist/capital-gains/india/IndiaCapitalGainsServiceImpl.js +58 -0
- package/dist/capital-gains/india/domain/types.js +3 -0
- package/dist/capital-gains/israel/IsraelCapitalGainsService.js +3 -0
- package/dist/capital-gains/israel/IsraelCapitalGainsServiceImpl.js +56 -0
- package/dist/capital-gains/israel/domain/types.js +3 -0
- package/dist/capital-gains/japan/JapanCapitalGainsService.js +3 -0
- package/dist/capital-gains/japan/JapanCapitalGainsServiceImpl.js +41 -0
- package/dist/capital-gains/japan/domain/types.js +3 -0
- package/dist/capital-gains/spain/SpainCapitalGainsService.js +3 -0
- package/dist/capital-gains/spain/SpainCapitalGainsServiceImpl.js +56 -0
- package/dist/capital-gains/spain/domain/types.js +3 -0
- package/dist/corporate/brazil/BrazilCorporateTaxService.js +3 -0
- package/dist/corporate/brazil/BrazilCorporateTaxServiceImpl.js +33 -0
- package/dist/corporate/brazil/domain/types.js +3 -0
- package/dist/corporate/index.js +19 -2
- package/dist/corporate/india/IndiaCorporateTaxService.js +3 -0
- package/dist/corporate/india/IndiaCorporateTaxServiceImpl.js +29 -0
- package/dist/corporate/india/domain/types.js +3 -0
- package/dist/corporate/israel/IsraelCorporateTaxService.js +3 -0
- package/dist/corporate/israel/IsraelCorporateTaxServiceImpl.js +29 -0
- package/dist/corporate/israel/domain/types.js +3 -0
- package/dist/corporate/japan/JapanCorporateTaxService.js +3 -0
- package/dist/corporate/japan/JapanCorporateTaxServiceImpl.js +29 -0
- package/dist/corporate/japan/domain/types.js +3 -0
- package/dist/corporate/netherlands/NetherlandsCorporateTaxService.js +3 -0
- package/dist/corporate/netherlands/NetherlandsCorporateTaxServiceImpl.js +40 -0
- package/dist/corporate/netherlands/domain/types.js +3 -0
- package/dist/corporate/spain/SpainCorporateTaxService.js +3 -0
- package/dist/corporate/spain/SpainCorporateTaxServiceImpl.js +29 -0
- package/dist/corporate/spain/domain/types.js +3 -0
- package/dist/corporate/switzerland/SwitzerlandCorporateTaxService.js +3 -0
- package/dist/corporate/switzerland/SwitzerlandCorporateTaxServiceImpl.js +29 -0
- package/dist/corporate/switzerland/domain/types.js +3 -0
- package/dist/income-tax/brazil/BrazilIncomeTaxService.js +3 -0
- package/dist/income-tax/brazil/BrazilIncomeTaxServiceImpl.js +78 -0
- package/dist/income-tax/brazil/domain/types.js +3 -0
- package/dist/income-tax/index.js +23 -2
- package/dist/income-tax/india/IndiaIncomeTaxService.js +3 -0
- package/dist/income-tax/india/IndiaIncomeTaxServiceImpl.js +75 -0
- package/dist/income-tax/india/domain/types.js +3 -0
- package/dist/income-tax/israel/IsraelIncomeTaxService.js +3 -0
- package/dist/income-tax/israel/IsraelIncomeTaxServiceImpl.js +62 -0
- package/dist/income-tax/israel/domain/types.js +3 -0
- package/dist/income-tax/japan/JapanIncomeTaxService.js +3 -0
- package/dist/income-tax/japan/JapanIncomeTaxServiceImpl.js +75 -0
- package/dist/income-tax/japan/domain/types.js +3 -0
- package/dist/income-tax/netherlands/NetherlandsIncomeTaxService.js +3 -0
- package/dist/income-tax/netherlands/NetherlandsIncomeTaxServiceImpl.js +62 -0
- package/dist/income-tax/netherlands/domain/types.js +3 -0
- package/dist/income-tax/spain/SpainIncomeTaxService.js +3 -0
- package/dist/income-tax/spain/SpainIncomeTaxServiceImpl.js +62 -0
- package/dist/income-tax/spain/domain/types.js +3 -0
- package/dist/income-tax/switzerland/SwitzerlandIncomeTaxService.js +3 -0
- package/dist/income-tax/switzerland/SwitzerlandIncomeTaxServiceImpl.js +62 -0
- package/dist/income-tax/switzerland/domain/types.js +3 -0
- package/dist/inheritance-tax/index.js +11 -2
- package/dist/inheritance-tax/japan/JapanInheritanceTaxService.js +3 -0
- package/dist/inheritance-tax/japan/JapanInheritanceTaxServiceImpl.js +53 -0
- package/dist/inheritance-tax/japan/domain/types.js +3 -0
- package/dist/inheritance-tax/netherlands/NetherlandsInheritanceTaxService.js +3 -0
- package/dist/inheritance-tax/netherlands/NetherlandsInheritanceTaxServiceImpl.js +52 -0
- package/dist/inheritance-tax/netherlands/domain/types.js +3 -0
- package/dist/inheritance-tax/spain/SpainInheritanceTaxService.js +3 -0
- package/dist/inheritance-tax/spain/SpainInheritanceTaxServiceImpl.js +51 -0
- package/dist/inheritance-tax/spain/domain/types.js +3 -0
- package/dist/mortgage/brazil/BrazilMortgageService.js +3 -0
- package/dist/mortgage/brazil/BrazilMortgageServiceImpl.js +76 -0
- package/dist/mortgage/brazil/domain/types.js +3 -0
- package/dist/mortgage/index.js +23 -2
- package/dist/mortgage/india/IndiaMortgageService.js +3 -0
- package/dist/mortgage/india/IndiaMortgageServiceImpl.js +76 -0
- package/dist/mortgage/india/domain/types.js +3 -0
- package/dist/mortgage/israel/IsraelMortgageService.js +3 -0
- package/dist/mortgage/israel/IsraelMortgageServiceImpl.js +100 -0
- package/dist/mortgage/israel/domain/types.js +3 -0
- package/dist/mortgage/japan/JapanMortgageService.js +3 -0
- package/dist/mortgage/japan/JapanMortgageServiceImpl.js +76 -0
- package/dist/mortgage/japan/domain/types.js +3 -0
- package/dist/mortgage/netherlands/NetherlandsMortgageService.js +3 -0
- package/dist/mortgage/netherlands/NetherlandsMortgageServiceImpl.js +83 -0
- package/dist/mortgage/netherlands/domain/types.js +3 -0
- package/dist/mortgage/spain/SpainMortgageService.js +3 -0
- package/dist/mortgage/spain/SpainMortgageServiceImpl.js +96 -0
- package/dist/mortgage/spain/domain/types.js +3 -0
- package/dist/mortgage/switzerland/SwitzerlandMortgageService.js +3 -0
- package/dist/mortgage/switzerland/SwitzerlandMortgageServiceImpl.js +80 -0
- package/dist/mortgage/switzerland/domain/types.js +3 -0
- package/dist/types/capital-gains/brazil/BrazilCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/brazil/BrazilCapitalGainsServiceImpl.d.ts +10 -0
- package/dist/types/capital-gains/brazil/domain/types.d.ts +11 -0
- package/dist/types/capital-gains/index.d.ts +11 -1
- package/dist/types/capital-gains/india/IndiaCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/india/IndiaCapitalGainsServiceImpl.d.ts +9 -0
- package/dist/types/capital-gains/india/domain/types.d.ts +9 -0
- package/dist/types/capital-gains/israel/IsraelCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/israel/IsraelCapitalGainsServiceImpl.d.ts +10 -0
- package/dist/types/capital-gains/israel/domain/types.d.ts +11 -0
- package/dist/types/capital-gains/japan/JapanCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/japan/JapanCapitalGainsServiceImpl.d.ts +9 -0
- package/dist/types/capital-gains/japan/domain/types.d.ts +6 -0
- package/dist/types/capital-gains/spain/SpainCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/spain/SpainCapitalGainsServiceImpl.d.ts +10 -0
- package/dist/types/capital-gains/spain/domain/types.d.ts +11 -0
- package/dist/types/corporate/brazil/BrazilCorporateTaxService.d.ts +4 -0
- package/dist/types/corporate/brazil/BrazilCorporateTaxServiceImpl.d.ts +8 -0
- package/dist/types/corporate/brazil/domain/types.d.ts +19 -0
- package/dist/types/corporate/index.d.ts +15 -1
- package/dist/types/corporate/india/IndiaCorporateTaxService.d.ts +4 -0
- package/dist/types/corporate/india/IndiaCorporateTaxServiceImpl.d.ts +8 -0
- package/dist/types/corporate/india/domain/types.d.ts +15 -0
- package/dist/types/corporate/israel/IsraelCorporateTaxService.d.ts +4 -0
- package/dist/types/corporate/israel/IsraelCorporateTaxServiceImpl.d.ts +8 -0
- package/dist/types/corporate/israel/domain/types.d.ts +15 -0
- package/dist/types/corporate/japan/JapanCorporateTaxService.d.ts +4 -0
- package/dist/types/corporate/japan/JapanCorporateTaxServiceImpl.d.ts +8 -0
- package/dist/types/corporate/japan/domain/types.d.ts +15 -0
- package/dist/types/corporate/netherlands/NetherlandsCorporateTaxService.d.ts +4 -0
- package/dist/types/corporate/netherlands/NetherlandsCorporateTaxServiceImpl.d.ts +8 -0
- package/dist/types/corporate/netherlands/domain/types.d.ts +17 -0
- package/dist/types/corporate/spain/SpainCorporateTaxService.d.ts +4 -0
- package/dist/types/corporate/spain/SpainCorporateTaxServiceImpl.d.ts +8 -0
- package/dist/types/corporate/spain/domain/types.d.ts +15 -0
- package/dist/types/corporate/switzerland/SwitzerlandCorporateTaxService.d.ts +4 -0
- package/dist/types/corporate/switzerland/SwitzerlandCorporateTaxServiceImpl.d.ts +8 -0
- package/dist/types/corporate/switzerland/domain/types.d.ts +15 -0
- package/dist/types/income-tax/brazil/BrazilIncomeTaxService.d.ts +4 -0
- package/dist/types/income-tax/brazil/BrazilIncomeTaxServiceImpl.d.ts +11 -0
- package/dist/types/income-tax/brazil/domain/types.d.ts +18 -0
- package/dist/types/income-tax/index.d.ts +15 -1
- package/dist/types/income-tax/india/IndiaIncomeTaxService.d.ts +4 -0
- package/dist/types/income-tax/india/IndiaIncomeTaxServiceImpl.d.ts +10 -0
- package/dist/types/income-tax/india/domain/types.d.ts +16 -0
- package/dist/types/income-tax/israel/IsraelIncomeTaxService.d.ts +4 -0
- package/dist/types/income-tax/israel/IsraelIncomeTaxServiceImpl.d.ts +10 -0
- package/dist/types/income-tax/israel/domain/types.d.ts +16 -0
- package/dist/types/income-tax/japan/JapanIncomeTaxService.d.ts +4 -0
- package/dist/types/income-tax/japan/JapanIncomeTaxServiceImpl.d.ts +10 -0
- package/dist/types/income-tax/japan/domain/types.d.ts +16 -0
- package/dist/types/income-tax/netherlands/NetherlandsIncomeTaxService.d.ts +4 -0
- package/dist/types/income-tax/netherlands/NetherlandsIncomeTaxServiceImpl.d.ts +10 -0
- package/dist/types/income-tax/netherlands/domain/types.d.ts +16 -0
- package/dist/types/income-tax/spain/SpainIncomeTaxService.d.ts +4 -0
- package/dist/types/income-tax/spain/SpainIncomeTaxServiceImpl.d.ts +10 -0
- package/dist/types/income-tax/spain/domain/types.d.ts +16 -0
- package/dist/types/income-tax/switzerland/SwitzerlandIncomeTaxService.d.ts +4 -0
- package/dist/types/income-tax/switzerland/SwitzerlandIncomeTaxServiceImpl.d.ts +10 -0
- package/dist/types/income-tax/switzerland/domain/types.d.ts +16 -0
- package/dist/types/inheritance-tax/index.d.ts +7 -1
- package/dist/types/inheritance-tax/japan/JapanInheritanceTaxService.d.ts +4 -0
- package/dist/types/inheritance-tax/japan/JapanInheritanceTaxServiceImpl.d.ts +9 -0
- package/dist/types/inheritance-tax/japan/domain/types.d.ts +21 -0
- package/dist/types/inheritance-tax/netherlands/NetherlandsInheritanceTaxService.d.ts +4 -0
- package/dist/types/inheritance-tax/netherlands/NetherlandsInheritanceTaxServiceImpl.d.ts +9 -0
- package/dist/types/inheritance-tax/netherlands/domain/types.d.ts +28 -0
- package/dist/types/inheritance-tax/spain/SpainInheritanceTaxService.d.ts +4 -0
- package/dist/types/inheritance-tax/spain/SpainInheritanceTaxServiceImpl.d.ts +9 -0
- package/dist/types/inheritance-tax/spain/domain/types.d.ts +19 -0
- package/dist/types/mortgage/brazil/BrazilMortgageService.d.ts +4 -0
- package/dist/types/mortgage/brazil/BrazilMortgageServiceImpl.d.ts +7 -0
- package/dist/types/mortgage/brazil/domain/types.d.ts +39 -0
- package/dist/types/mortgage/index.d.ts +15 -1
- package/dist/types/mortgage/india/IndiaMortgageService.d.ts +4 -0
- package/dist/types/mortgage/india/IndiaMortgageServiceImpl.d.ts +7 -0
- package/dist/types/mortgage/india/domain/types.d.ts +39 -0
- package/dist/types/mortgage/israel/IsraelMortgageService.d.ts +4 -0
- package/dist/types/mortgage/israel/IsraelMortgageServiceImpl.d.ts +8 -0
- package/dist/types/mortgage/israel/domain/types.d.ts +43 -0
- package/dist/types/mortgage/japan/JapanMortgageService.d.ts +4 -0
- package/dist/types/mortgage/japan/JapanMortgageServiceImpl.d.ts +7 -0
- package/dist/types/mortgage/japan/domain/types.d.ts +39 -0
- package/dist/types/mortgage/netherlands/NetherlandsMortgageService.d.ts +4 -0
- package/dist/types/mortgage/netherlands/NetherlandsMortgageServiceImpl.d.ts +7 -0
- package/dist/types/mortgage/netherlands/domain/types.d.ts +41 -0
- package/dist/types/mortgage/spain/SpainMortgageService.d.ts +4 -0
- package/dist/types/mortgage/spain/SpainMortgageServiceImpl.d.ts +8 -0
- package/dist/types/mortgage/spain/domain/types.d.ts +44 -0
- package/dist/types/mortgage/switzerland/SwitzerlandMortgageService.d.ts +4 -0
- package/dist/types/mortgage/switzerland/SwitzerlandMortgageServiceImpl.d.ts +7 -0
- package/dist/types/mortgage/switzerland/domain/types.d.ts +37 -0
- package/package.json +1 -1
- package/src/capital-gains/brazil/BrazilCapitalGainsService.ts +5 -0
- package/src/capital-gains/brazil/BrazilCapitalGainsServiceImpl.ts +69 -0
- package/src/capital-gains/brazil/domain/types.ts +15 -0
- package/src/capital-gains/index.ts +50 -0
- package/src/capital-gains/india/IndiaCapitalGainsService.ts +5 -0
- package/src/capital-gains/india/IndiaCapitalGainsServiceImpl.ts +64 -0
- package/src/capital-gains/india/domain/types.ts +12 -0
- package/src/capital-gains/israel/IsraelCapitalGainsService.ts +5 -0
- package/src/capital-gains/israel/IsraelCapitalGainsServiceImpl.ts +69 -0
- package/src/capital-gains/israel/domain/types.ts +15 -0
- package/src/capital-gains/japan/JapanCapitalGainsService.ts +5 -0
- package/src/capital-gains/japan/JapanCapitalGainsServiceImpl.ts +47 -0
- package/src/capital-gains/japan/domain/types.ts +9 -0
- package/src/capital-gains/spain/SpainCapitalGainsService.ts +5 -0
- package/src/capital-gains/spain/SpainCapitalGainsServiceImpl.ts +69 -0
- package/src/capital-gains/spain/domain/types.ts +15 -0
- package/src/corporate/brazil/BrazilCorporateTaxService.ts +5 -0
- package/src/corporate/brazil/BrazilCorporateTaxServiceImpl.ts +40 -0
- package/src/corporate/brazil/domain/types.ts +16 -0
- package/src/corporate/index.ts +81 -1
- package/src/corporate/india/IndiaCorporateTaxService.ts +5 -0
- package/src/corporate/india/IndiaCorporateTaxServiceImpl.ts +35 -0
- package/src/corporate/india/domain/types.ts +15 -0
- package/src/corporate/israel/IsraelCorporateTaxService.ts +5 -0
- package/src/corporate/israel/IsraelCorporateTaxServiceImpl.ts +35 -0
- package/src/corporate/israel/domain/types.ts +15 -0
- package/src/corporate/japan/JapanCorporateTaxService.ts +5 -0
- package/src/corporate/japan/JapanCorporateTaxServiceImpl.ts +35 -0
- package/src/corporate/japan/domain/types.ts +15 -0
- package/src/corporate/netherlands/NetherlandsCorporateTaxService.ts +5 -0
- package/src/corporate/netherlands/NetherlandsCorporateTaxServiceImpl.ts +48 -0
- package/src/corporate/netherlands/domain/types.ts +21 -0
- package/src/corporate/spain/SpainCorporateTaxService.ts +5 -0
- package/src/corporate/spain/SpainCorporateTaxServiceImpl.ts +35 -0
- package/src/corporate/spain/domain/types.ts +15 -0
- package/src/corporate/switzerland/SwitzerlandCorporateTaxService.ts +5 -0
- package/src/corporate/switzerland/SwitzerlandCorporateTaxServiceImpl.ts +35 -0
- package/src/corporate/switzerland/domain/types.ts +15 -0
- package/src/income-tax/brazil/BrazilIncomeTaxService.ts +5 -0
- package/src/income-tax/brazil/BrazilIncomeTaxServiceImpl.ts +91 -0
- package/src/income-tax/brazil/domain/types.ts +21 -0
- package/src/income-tax/index.ts +70 -0
- package/src/income-tax/india/IndiaIncomeTaxService.ts +5 -0
- package/src/income-tax/india/IndiaIncomeTaxServiceImpl.ts +87 -0
- package/src/income-tax/india/domain/types.ts +16 -0
- package/src/income-tax/israel/IsraelIncomeTaxService.ts +5 -0
- package/src/income-tax/israel/IsraelIncomeTaxServiceImpl.ts +75 -0
- package/src/income-tax/israel/domain/types.ts +16 -0
- package/src/income-tax/japan/JapanIncomeTaxService.ts +5 -0
- package/src/income-tax/japan/JapanIncomeTaxServiceImpl.ts +87 -0
- package/src/income-tax/japan/domain/types.ts +16 -0
- package/src/income-tax/netherlands/NetherlandsIncomeTaxService.ts +5 -0
- package/src/income-tax/netherlands/NetherlandsIncomeTaxServiceImpl.ts +75 -0
- package/src/income-tax/netherlands/domain/types.ts +16 -0
- package/src/income-tax/spain/SpainIncomeTaxService.ts +5 -0
- package/src/income-tax/spain/SpainIncomeTaxServiceImpl.ts +75 -0
- package/src/income-tax/spain/domain/types.ts +16 -0
- package/src/income-tax/switzerland/SwitzerlandIncomeTaxService.ts +5 -0
- package/src/income-tax/switzerland/SwitzerlandIncomeTaxServiceImpl.ts +75 -0
- package/src/income-tax/switzerland/domain/types.ts +16 -0
- package/src/inheritance-tax/index.ts +36 -0
- package/src/inheritance-tax/japan/JapanInheritanceTaxService.ts +5 -0
- package/src/inheritance-tax/japan/JapanInheritanceTaxServiceImpl.ts +67 -0
- package/src/inheritance-tax/japan/domain/types.ts +25 -0
- package/src/inheritance-tax/netherlands/NetherlandsInheritanceTaxService.ts +5 -0
- package/src/inheritance-tax/netherlands/NetherlandsInheritanceTaxServiceImpl.ts +66 -0
- package/src/inheritance-tax/netherlands/domain/types.ts +34 -0
- package/src/inheritance-tax/spain/SpainInheritanceTaxService.ts +5 -0
- package/src/inheritance-tax/spain/SpainInheritanceTaxServiceImpl.ts +65 -0
- package/src/inheritance-tax/spain/domain/types.ts +23 -0
- package/src/mortgage/brazil/BrazilMortgageService.ts +5 -0
- package/src/mortgage/brazil/BrazilMortgageServiceImpl.ts +101 -0
- package/src/mortgage/brazil/domain/types.ts +46 -0
- package/src/mortgage/index.ts +85 -1
- package/src/mortgage/india/IndiaMortgageService.ts +5 -0
- package/src/mortgage/india/IndiaMortgageServiceImpl.ts +101 -0
- package/src/mortgage/india/domain/types.ts +46 -0
- package/src/mortgage/israel/IsraelMortgageService.ts +5 -0
- package/src/mortgage/israel/IsraelMortgageServiceImpl.ts +132 -0
- package/src/mortgage/israel/domain/types.ts +41 -0
- package/src/mortgage/japan/JapanMortgageService.ts +5 -0
- package/src/mortgage/japan/JapanMortgageServiceImpl.ts +101 -0
- package/src/mortgage/japan/domain/types.ts +46 -0
- package/src/mortgage/netherlands/NetherlandsMortgageService.ts +5 -0
- package/src/mortgage/netherlands/NetherlandsMortgageServiceImpl.ts +109 -0
- package/src/mortgage/netherlands/domain/types.ts +37 -0
- package/src/mortgage/spain/SpainMortgageService.ts +5 -0
- package/src/mortgage/spain/SpainMortgageServiceImpl.ts +130 -0
- package/src/mortgage/spain/domain/types.ts +52 -0
- package/src/mortgage/switzerland/SwitzerlandMortgageService.ts +5 -0
- package/src/mortgage/switzerland/SwitzerlandMortgageServiceImpl.ts +106 -0
- package/src/mortgage/switzerland/domain/types.ts +36 -0
- package/test/brazil-capital-gains.test.ts +65 -0
- package/test/brazil-corporate-tax.test.ts +63 -0
- package/test/brazil-income-tax.test.ts +85 -0
- package/test/brazil-mortgage.test.ts +70 -0
- package/test/india-capital-gains.test.ts +71 -0
- package/test/india-corporate-tax.test.ts +54 -0
- package/test/india-income-tax.test.ts +78 -0
- package/test/india-mortgage.test.ts +70 -0
- package/test/israel-capital-gains.test.ts +45 -0
- package/test/israel-corporate-tax.test.ts +49 -0
- package/test/israel-income-tax.test.ts +76 -0
- package/test/israel-mortgage.test.ts +80 -0
- package/test/japan-capital-gains.test.ts +55 -0
- package/test/japan-corporate-tax.test.ts +54 -0
- package/test/japan-income-tax.test.ts +76 -0
- package/test/japan-inheritance-tax.test.ts +74 -0
- package/test/japan-mortgage.test.ts +69 -0
- package/test/netherlands-corporate-tax.test.ts +54 -0
- package/test/netherlands-income-tax.test.ts +54 -0
- package/test/netherlands-inheritance-tax.test.ts +79 -0
- package/test/netherlands-mortgage.test.ts +79 -0
- package/test/spain-capital-gains.test.ts +66 -0
- package/test/spain-corporate-tax.test.ts +54 -0
- package/test/spain-income-tax.test.ts +84 -0
- package/test/spain-inheritance-tax.test.ts +78 -0
- package/test/spain-mortgage.test.ts +70 -0
- package/test/switzerland-corporate-tax.test.ts +39 -0
- package/test/switzerland-income-tax.test.ts +66 -0
- package/test/switzerland-mortgage.test.ts +70 -0
- package/dist/domain/types.js +0 -10
- package/dist/types/domain/types.d.ts +0 -41
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { BrazilIncomeTaxServiceImpl } from '../src/income-tax/brazil/BrazilIncomeTaxServiceImpl';
|
|
2
|
+
import { IncomeTaxRules } from '../src/income-tax/brazil/domain/types';
|
|
3
|
+
|
|
4
|
+
const brazilRules: IncomeTaxRules = {
|
|
5
|
+
taxBrackets: [
|
|
6
|
+
{ from: 0, to: 27110.40, rate: 0 },
|
|
7
|
+
{ from: 27110.40, to: 33919.80, rate: 0.075 },
|
|
8
|
+
{ from: 33919.80, to: 45012.60, rate: 0.15 },
|
|
9
|
+
{ from: 45012.60, to: 55976.16, rate: 0.225 },
|
|
10
|
+
{ from: 55976.16, to: null, rate: 0.275 },
|
|
11
|
+
],
|
|
12
|
+
inss: { rate: 0.11, cap: 87600 },
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
describe('BrazilIncomeTaxServiceImpl', () => {
|
|
16
|
+
it('returns zero tax for zero income', () => {
|
|
17
|
+
const service = new BrazilIncomeTaxServiceImpl(0, brazilRules);
|
|
18
|
+
const result = service.calculateNetIncome();
|
|
19
|
+
|
|
20
|
+
expect(result.incomeTax).toBe(0);
|
|
21
|
+
expect(result.inss).toBe(0);
|
|
22
|
+
expect(result.totalDeductions).toBe(0);
|
|
23
|
+
expect(result.effectiveTaxRate).toBe(0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('returns zero income tax for income in first bracket (below 27110.40)', () => {
|
|
27
|
+
const service = new BrazilIncomeTaxServiceImpl(20000, brazilRules);
|
|
28
|
+
const result = service.calculateNetIncome();
|
|
29
|
+
|
|
30
|
+
expect(result.incomeTax).toBe(0);
|
|
31
|
+
expect(result.grossIncome).toBe(20000);
|
|
32
|
+
// INSS = 20000 * 0.11 = 2200
|
|
33
|
+
expect(result.inss).toBeCloseTo(2200, 2);
|
|
34
|
+
expect(result.effectiveTaxRate).toBe(0);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('correctly calculates income tax for income spanning multiple brackets', () => {
|
|
38
|
+
const service = new BrazilIncomeTaxServiceImpl(50000, brazilRules);
|
|
39
|
+
const result = service.calculateNetIncome();
|
|
40
|
+
|
|
41
|
+
// 0-27110.40: 0 tax
|
|
42
|
+
// 27110.40-33919.80: 6809.40 * 0.075 = 510.705
|
|
43
|
+
// 33919.80-45012.60: 11092.80 * 0.15 = 1663.92
|
|
44
|
+
// 45012.60-50000: 4987.40 * 0.225 = 1122.165
|
|
45
|
+
// Total ≈ 3296.79
|
|
46
|
+
expect(result.incomeTax).toBeCloseTo(3296.79, 1);
|
|
47
|
+
expect(result.grossIncome).toBe(50000);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('correctly computes INSS and caps it at the cap amount', () => {
|
|
51
|
+
const service = new BrazilIncomeTaxServiceImpl(100000, brazilRules);
|
|
52
|
+
const result = service.calculateNetIncome();
|
|
53
|
+
|
|
54
|
+
// INSS is capped at 87600: 87600 * 0.11 = 9636
|
|
55
|
+
expect(result.inss).toBeCloseTo(9636, 2);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('calculates effective tax rate as income tax divided by gross income', () => {
|
|
59
|
+
const service = new BrazilIncomeTaxServiceImpl(50000, brazilRules);
|
|
60
|
+
const result = service.calculateNetIncome();
|
|
61
|
+
|
|
62
|
+
expect(result.effectiveTaxRate).toBeCloseTo(result.incomeTax / result.grossIncome, 4);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('net income equals gross income minus total deductions', () => {
|
|
66
|
+
const service = new BrazilIncomeTaxServiceImpl(50000, brazilRules);
|
|
67
|
+
const result = service.calculateNetIncome();
|
|
68
|
+
|
|
69
|
+
expect(result.netIncome).toBeCloseTo(result.grossIncome - result.totalDeductions, 2);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('total deductions equals income tax plus INSS', () => {
|
|
73
|
+
const service = new BrazilIncomeTaxServiceImpl(50000, brazilRules);
|
|
74
|
+
const result = service.calculateNetIncome();
|
|
75
|
+
|
|
76
|
+
expect(result.totalDeductions).toBeCloseTo(result.incomeTax + result.inss, 2);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('returns bracket breakdown entries for multi-bracket income', () => {
|
|
80
|
+
const service = new BrazilIncomeTaxServiceImpl(60000, brazilRules);
|
|
81
|
+
const result = service.calculateNetIncome();
|
|
82
|
+
|
|
83
|
+
expect(result.taxBracketBreakdown.length).toBeGreaterThan(0);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { BrazilMortgageServiceImpl } from '../src/mortgage/brazil/BrazilMortgageServiceImpl';
|
|
2
|
+
import { MortgageInput, MortgageRules } from '../src/mortgage/brazil/domain/types';
|
|
3
|
+
|
|
4
|
+
const brazilRules: MortgageRules = {
|
|
5
|
+
loanConstraints: { maxLtvPercent: 0.80, maxAmortizationYears: 35 },
|
|
6
|
+
interest: { compounding: 'MONTHLY' },
|
|
7
|
+
itbi: { rate: 0.02 },
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const input: MortgageInput = {
|
|
11
|
+
propertyPrice: 500000,
|
|
12
|
+
downPayment: 100000,
|
|
13
|
+
annualInterestRate: 10,
|
|
14
|
+
amortizationYears: 30,
|
|
15
|
+
isFirstTimeBuyer: false,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
describe('BrazilMortgageServiceImpl', () => {
|
|
19
|
+
it('correctly calculates the loan amount', () => {
|
|
20
|
+
const service = new BrazilMortgageServiceImpl();
|
|
21
|
+
const result = service.calculate(input, brazilRules);
|
|
22
|
+
|
|
23
|
+
// loanAmount = 500000 - 100000 = 400000
|
|
24
|
+
expect(result.loanAmount).toBe(400000);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('correctly calculates ITBI', () => {
|
|
28
|
+
const service = new BrazilMortgageServiceImpl();
|
|
29
|
+
const result = service.calculate(input, brazilRules);
|
|
30
|
+
|
|
31
|
+
// ITBI = 500000 * 0.02 = 10000
|
|
32
|
+
expect(result.itbi).toBe(10000);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('calculates a positive monthly payment', () => {
|
|
36
|
+
const service = new BrazilMortgageServiceImpl();
|
|
37
|
+
const result = service.calculate(input, brazilRules);
|
|
38
|
+
|
|
39
|
+
expect(result.monthlyPayment).toBeGreaterThan(0);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('total paid is greater than the loan amount', () => {
|
|
43
|
+
const service = new BrazilMortgageServiceImpl();
|
|
44
|
+
const result = service.calculate(input, brazilRules);
|
|
45
|
+
|
|
46
|
+
expect(result.totalPaid).toBeGreaterThan(result.loanAmount);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('amortization schedule has the correct number of years', () => {
|
|
50
|
+
const service = new BrazilMortgageServiceImpl();
|
|
51
|
+
const result = service.calculate(input, brazilRules);
|
|
52
|
+
|
|
53
|
+
expect(result.amortizationSchedule).toHaveLength(30);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('total paid equals monthly payment multiplied by total payments', () => {
|
|
57
|
+
const service = new BrazilMortgageServiceImpl();
|
|
58
|
+
const result = service.calculate(input, brazilRules);
|
|
59
|
+
|
|
60
|
+
const expectedTotal = result.monthlyPayment * (input.amortizationYears * 12);
|
|
61
|
+
expect(result.totalPaid).toBeCloseTo(expectedTotal, 2);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('throws an error when down payment equals or exceeds property price', () => {
|
|
65
|
+
const service = new BrazilMortgageServiceImpl();
|
|
66
|
+
const badInput: MortgageInput = { ...input, downPayment: 500000 };
|
|
67
|
+
|
|
68
|
+
expect(() => service.calculate(badInput, brazilRules)).toThrow();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { IndiaCapitalGainsServiceImpl } from '../src/capital-gains/india/IndiaCapitalGainsServiceImpl';
|
|
2
|
+
import { Input, Rules } from '../src/capital-gains/india/domain/types';
|
|
3
|
+
|
|
4
|
+
const indiaRules: Rules = {
|
|
5
|
+
shortTermRate: 0.20,
|
|
6
|
+
longTermRate: 0.125,
|
|
7
|
+
longTermExemption: 125000,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
describe('IndiaCapitalGainsServiceImpl', () => {
|
|
11
|
+
it('returns zero tax for zero gain', () => {
|
|
12
|
+
const input: Input = { capitalGain: 0, holdingPeriodMonths: 6 };
|
|
13
|
+
const service = new IndiaCapitalGainsServiceImpl(input, indiaRules);
|
|
14
|
+
const result = service.calculate();
|
|
15
|
+
|
|
16
|
+
expect(result.taxableGain).toBe(0);
|
|
17
|
+
expect(result.capitalGainTax).toBe(0);
|
|
18
|
+
expect(result.totalTax).toBe(0);
|
|
19
|
+
expect(result.effectiveRate).toBe(0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('correctly calculates short-term capital gains tax', () => {
|
|
23
|
+
const input: Input = { capitalGain: 500000, holdingPeriodMonths: 6 };
|
|
24
|
+
const service = new IndiaCapitalGainsServiceImpl(input, indiaRules);
|
|
25
|
+
const result = service.calculate();
|
|
26
|
+
|
|
27
|
+
// Short-term: 500000 * 0.20 = 100000
|
|
28
|
+
expect(result.capitalGainTax).toBe(100000);
|
|
29
|
+
expect(result.totalTax).toBe(100000);
|
|
30
|
+
expect(result.effectiveRate).toBeCloseTo(20, 2);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('returns zero tax for long-term gain fully within the exemption', () => {
|
|
34
|
+
const input: Input = { capitalGain: 100000, holdingPeriodMonths: 24 };
|
|
35
|
+
const service = new IndiaCapitalGainsServiceImpl(input, indiaRules);
|
|
36
|
+
const result = service.calculate();
|
|
37
|
+
|
|
38
|
+
// Long-term: max(0, 100000 - 125000) = 0 taxable
|
|
39
|
+
expect(result.capitalGainTax).toBe(0);
|
|
40
|
+
expect(result.totalTax).toBe(0);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('correctly calculates long-term capital gains above the exemption', () => {
|
|
44
|
+
const input: Input = { capitalGain: 500000, holdingPeriodMonths: 24 };
|
|
45
|
+
const service = new IndiaCapitalGainsServiceImpl(input, indiaRules);
|
|
46
|
+
const result = service.calculate();
|
|
47
|
+
|
|
48
|
+
// Long-term: max(0, 500000 - 125000) = 375000 * 0.125 = 46875
|
|
49
|
+
expect(result.capitalGainTax).toBe(46875);
|
|
50
|
+
expect(result.totalTax).toBe(46875);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('long-term rate is lower than short-term rate for the same gain', () => {
|
|
54
|
+
const longTermInput: Input = { capitalGain: 500000, holdingPeriodMonths: 24 };
|
|
55
|
+
const shortTermInput: Input = { capitalGain: 500000, holdingPeriodMonths: 6 };
|
|
56
|
+
|
|
57
|
+
const longTermTax = new IndiaCapitalGainsServiceImpl(longTermInput, indiaRules).calculate().capitalGainTax;
|
|
58
|
+
const shortTermTax = new IndiaCapitalGainsServiceImpl(shortTermInput, indiaRules).calculate().capitalGainTax;
|
|
59
|
+
|
|
60
|
+
expect(longTermTax).toBeLessThan(shortTermTax);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('holding period of exactly 12 months is treated as long-term', () => {
|
|
64
|
+
const input: Input = { capitalGain: 500000, holdingPeriodMonths: 12 };
|
|
65
|
+
const service = new IndiaCapitalGainsServiceImpl(input, indiaRules);
|
|
66
|
+
const result = service.calculate();
|
|
67
|
+
|
|
68
|
+
// Long-term: max(0, 500000 - 125000) = 375000 * 0.125 = 46875
|
|
69
|
+
expect(result.capitalGainTax).toBe(46875);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { IndiaCorporateTaxServiceImpl } from '../src/corporate/india/IndiaCorporateTaxServiceImpl';
|
|
2
|
+
import { Input, Rules } from '../src/corporate/india/domain/types';
|
|
3
|
+
|
|
4
|
+
const indiaRules: Rules = {
|
|
5
|
+
regime: { type: 'flat', rate: 0.22 },
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
describe('IndiaCorporateTaxServiceImpl', () => {
|
|
9
|
+
it('returns zero tax for zero income', () => {
|
|
10
|
+
const input: Input = { taxableIncome: 0 };
|
|
11
|
+
const service = new IndiaCorporateTaxServiceImpl(input, indiaRules);
|
|
12
|
+
const result = service.calculate();
|
|
13
|
+
|
|
14
|
+
expect(result.corporateTax).toBe(0);
|
|
15
|
+
expect(result.effectiveTaxRate).toBe(0);
|
|
16
|
+
expect(result.breakdowns).toHaveLength(0);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('correctly applies the flat 22% rate', () => {
|
|
20
|
+
const input: Input = { taxableIncome: 1000000 };
|
|
21
|
+
const service = new IndiaCorporateTaxServiceImpl(input, indiaRules);
|
|
22
|
+
const result = service.calculate();
|
|
23
|
+
|
|
24
|
+
// 1000000 * 0.22 = 220000
|
|
25
|
+
expect(result.corporateTax).toBe(220000);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('calculates effective tax rate as percentage', () => {
|
|
29
|
+
const input: Input = { taxableIncome: 1000000 };
|
|
30
|
+
const service = new IndiaCorporateTaxServiceImpl(input, indiaRules);
|
|
31
|
+
const result = service.calculate();
|
|
32
|
+
|
|
33
|
+
expect(result.effectiveTaxRate).toBe(22);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('returns one breakdown entry for flat rate calculation', () => {
|
|
37
|
+
const input: Input = { taxableIncome: 1000000 };
|
|
38
|
+
const service = new IndiaCorporateTaxServiceImpl(input, indiaRules);
|
|
39
|
+
const result = service.calculate();
|
|
40
|
+
|
|
41
|
+
expect(result.breakdowns).toHaveLength(1);
|
|
42
|
+
expect(result.breakdowns[0].rate).toBe(0.22);
|
|
43
|
+
expect(result.breakdowns[0].amount).toBe(220000);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('scales linearly with taxable income', () => {
|
|
47
|
+
const input: Input = { taxableIncome: 5000000 };
|
|
48
|
+
const service = new IndiaCorporateTaxServiceImpl(input, indiaRules);
|
|
49
|
+
const result = service.calculate();
|
|
50
|
+
|
|
51
|
+
expect(result.corporateTax).toBe(1100000);
|
|
52
|
+
expect(result.effectiveTaxRate).toBe(22);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { IndiaIncomeTaxServiceImpl } from '../src/income-tax/india/IndiaIncomeTaxServiceImpl';
|
|
2
|
+
import { IncomeTaxRules } from '../src/income-tax/india/domain/types';
|
|
3
|
+
|
|
4
|
+
const indiaRules: IncomeTaxRules = {
|
|
5
|
+
taxBrackets: [
|
|
6
|
+
{ from: 0, to: 300000, rate: 0 },
|
|
7
|
+
{ from: 300000, to: 700000, rate: 0.05 },
|
|
8
|
+
{ from: 700000, to: 1000000, rate: 0.10 },
|
|
9
|
+
{ from: 1000000, to: 1200000, rate: 0.15 },
|
|
10
|
+
{ from: 1200000, to: 1500000, rate: 0.20 },
|
|
11
|
+
{ from: 1500000, to: null, rate: 0.30 },
|
|
12
|
+
],
|
|
13
|
+
cess: { rate: 0.04 },
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe('IndiaIncomeTaxServiceImpl', () => {
|
|
17
|
+
it('returns zero tax for zero income', () => {
|
|
18
|
+
const service = new IndiaIncomeTaxServiceImpl(0, indiaRules);
|
|
19
|
+
const result = service.calculateNetIncome();
|
|
20
|
+
|
|
21
|
+
expect(result.incomeTax).toBe(0);
|
|
22
|
+
expect(result.cess).toBe(0);
|
|
23
|
+
expect(result.totalDeductions).toBe(0);
|
|
24
|
+
expect(result.effectiveTaxRate).toBe(0);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('returns zero income tax for income below the basic exemption (300000)', () => {
|
|
28
|
+
const service = new IndiaIncomeTaxServiceImpl(200000, indiaRules);
|
|
29
|
+
const result = service.calculateNetIncome();
|
|
30
|
+
|
|
31
|
+
expect(result.incomeTax).toBe(0);
|
|
32
|
+
expect(result.cess).toBe(0);
|
|
33
|
+
expect(result.grossIncome).toBe(200000);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('correctly calculates tax and cess for income spanning multiple brackets', () => {
|
|
37
|
+
const service = new IndiaIncomeTaxServiceImpl(800000, indiaRules);
|
|
38
|
+
const result = service.calculateNetIncome();
|
|
39
|
+
|
|
40
|
+
// 0-300000: 0 tax
|
|
41
|
+
// 300000-700000: 400000 * 0.05 = 20000
|
|
42
|
+
// 700000-800000: 100000 * 0.10 = 10000
|
|
43
|
+
// grossTax = 30000
|
|
44
|
+
// cess = 30000 * 0.04 = 1200
|
|
45
|
+
expect(result.incomeTax).toBeCloseTo(30000, 2);
|
|
46
|
+
expect(result.cess).toBeCloseTo(1200, 2);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('correctly calculates total deductions as income tax plus cess', () => {
|
|
50
|
+
const service = new IndiaIncomeTaxServiceImpl(800000, indiaRules);
|
|
51
|
+
const result = service.calculateNetIncome();
|
|
52
|
+
|
|
53
|
+
expect(result.totalDeductions).toBeCloseTo(result.incomeTax + result.cess, 2);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('net income equals gross income minus total deductions', () => {
|
|
57
|
+
const service = new IndiaIncomeTaxServiceImpl(800000, indiaRules);
|
|
58
|
+
const result = service.calculateNetIncome();
|
|
59
|
+
|
|
60
|
+
expect(result.netIncome).toBeCloseTo(result.grossIncome - result.totalDeductions, 2);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('calculates effective tax rate as income tax divided by gross income', () => {
|
|
64
|
+
const service = new IndiaIncomeTaxServiceImpl(1000000, indiaRules);
|
|
65
|
+
const result = service.calculateNetIncome();
|
|
66
|
+
|
|
67
|
+
expect(result.effectiveTaxRate).toBeCloseTo(result.incomeTax / result.grossIncome, 4);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('correctly applies the top bracket for high income', () => {
|
|
71
|
+
const service = new IndiaIncomeTaxServiceImpl(2000000, indiaRules);
|
|
72
|
+
const result = service.calculateNetIncome();
|
|
73
|
+
|
|
74
|
+
expect(result.incomeTax).toBeGreaterThan(0);
|
|
75
|
+
const lastBreakdown = result.taxBracketBreakdown[result.taxBracketBreakdown.length - 1];
|
|
76
|
+
expect(lastBreakdown.rate).toBe(0.30);
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { IndiaMortgageServiceImpl } from '../src/mortgage/india/IndiaMortgageServiceImpl';
|
|
2
|
+
import { MortgageInput, MortgageRules } from '../src/mortgage/india/domain/types';
|
|
3
|
+
|
|
4
|
+
const indiaRules: MortgageRules = {
|
|
5
|
+
loanConstraints: { maxLtvPercent: 0.75, maxAmortizationYears: 30 },
|
|
6
|
+
interest: { compounding: 'MONTHLY' },
|
|
7
|
+
stampDuty: { rate: 0.05 },
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const input: MortgageInput = {
|
|
11
|
+
propertyPrice: 10000000,
|
|
12
|
+
downPayment: 2000000,
|
|
13
|
+
annualInterestRate: 8.5,
|
|
14
|
+
amortizationYears: 20,
|
|
15
|
+
isFirstTimeBuyer: false,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
describe('IndiaMortgageServiceImpl', () => {
|
|
19
|
+
it('correctly calculates the loan amount', () => {
|
|
20
|
+
const service = new IndiaMortgageServiceImpl();
|
|
21
|
+
const result = service.calculate(input, indiaRules);
|
|
22
|
+
|
|
23
|
+
// loanAmount = 10000000 - 2000000 = 8000000
|
|
24
|
+
expect(result.loanAmount).toBe(8000000);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('correctly calculates stamp duty', () => {
|
|
28
|
+
const service = new IndiaMortgageServiceImpl();
|
|
29
|
+
const result = service.calculate(input, indiaRules);
|
|
30
|
+
|
|
31
|
+
// stampDuty = 10000000 * 0.05 = 500000
|
|
32
|
+
expect(result.stampDuty).toBe(500000);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('calculates a positive monthly payment', () => {
|
|
36
|
+
const service = new IndiaMortgageServiceImpl();
|
|
37
|
+
const result = service.calculate(input, indiaRules);
|
|
38
|
+
|
|
39
|
+
expect(result.monthlyPayment).toBeGreaterThan(0);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('total paid is greater than the loan amount', () => {
|
|
43
|
+
const service = new IndiaMortgageServiceImpl();
|
|
44
|
+
const result = service.calculate(input, indiaRules);
|
|
45
|
+
|
|
46
|
+
expect(result.totalPaid).toBeGreaterThan(result.loanAmount);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('amortization schedule has the correct number of years', () => {
|
|
50
|
+
const service = new IndiaMortgageServiceImpl();
|
|
51
|
+
const result = service.calculate(input, indiaRules);
|
|
52
|
+
|
|
53
|
+
expect(result.amortizationSchedule).toHaveLength(20);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('total paid equals monthly payment multiplied by total payments', () => {
|
|
57
|
+
const service = new IndiaMortgageServiceImpl();
|
|
58
|
+
const result = service.calculate(input, indiaRules);
|
|
59
|
+
|
|
60
|
+
const expectedTotal = result.monthlyPayment * (input.amortizationYears * 12);
|
|
61
|
+
expect(result.totalPaid).toBeCloseTo(expectedTotal, 2);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('throws an error when down payment equals or exceeds property price', () => {
|
|
65
|
+
const service = new IndiaMortgageServiceImpl();
|
|
66
|
+
const badInput: MortgageInput = { ...input, downPayment: 10000000 };
|
|
67
|
+
|
|
68
|
+
expect(() => service.calculate(badInput, indiaRules)).toThrow();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { IsraelCapitalGainsServiceImpl } from '../src/capital-gains/israel/IsraelCapitalGainsServiceImpl';
|
|
2
|
+
import { Input, Rules } from '../src/capital-gains/israel/domain/types';
|
|
3
|
+
|
|
4
|
+
const israelRules: Rules = {
|
|
5
|
+
brackets: [
|
|
6
|
+
{ from: 0, to: null, rate: 0.25 },
|
|
7
|
+
],
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
describe('IsraelCapitalGainsServiceImpl', () => {
|
|
11
|
+
it('returns zero tax for zero gain', () => {
|
|
12
|
+
const input: Input = { capitalGain: 0 };
|
|
13
|
+
const service = new IsraelCapitalGainsServiceImpl(input, israelRules);
|
|
14
|
+
const result = service.calculate();
|
|
15
|
+
expect(result.taxableGain).toBe(0);
|
|
16
|
+
expect(result.capitalGainTax).toBe(0);
|
|
17
|
+
expect(result.totalTax).toBe(0);
|
|
18
|
+
expect(result.effectiveRate).toBe(0);
|
|
19
|
+
expect(result.breakdowns).toHaveLength(0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('correctly calculates flat 25% tax', () => {
|
|
23
|
+
const input: Input = { capitalGain: 100000 };
|
|
24
|
+
const service = new IsraelCapitalGainsServiceImpl(input, israelRules);
|
|
25
|
+
const result = service.calculate();
|
|
26
|
+
// 100000 * 0.25 = 25000
|
|
27
|
+
expect(result.capitalGainTax).toBe(25000);
|
|
28
|
+
expect(result.totalTax).toBe(25000);
|
|
29
|
+
expect(result.effectiveRate).toBe(25);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('taxable gain equals input capital gain', () => {
|
|
33
|
+
const input: Input = { capitalGain: 50000 };
|
|
34
|
+
const service = new IsraelCapitalGainsServiceImpl(input, israelRules);
|
|
35
|
+
const result = service.calculate();
|
|
36
|
+
expect(result.taxableGain).toBe(50000);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('effective rate equals total tax divided by gain times 100', () => {
|
|
40
|
+
const input: Input = { capitalGain: 200000 };
|
|
41
|
+
const service = new IsraelCapitalGainsServiceImpl(input, israelRules);
|
|
42
|
+
const result = service.calculate();
|
|
43
|
+
expect(result.effectiveRate).toBeCloseTo((result.capitalGainTax / 200000) * 100, 2);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { IsraelCorporateTaxServiceImpl } from '../src/corporate/israel/IsraelCorporateTaxServiceImpl';
|
|
2
|
+
import { Input, Rules } from '../src/corporate/israel/domain/types';
|
|
3
|
+
|
|
4
|
+
const israelRules: Rules = {
|
|
5
|
+
regime: { type: 'flat', rate: 0.23 },
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
describe('IsraelCorporateTaxServiceImpl', () => {
|
|
9
|
+
it('returns zero tax for zero income', () => {
|
|
10
|
+
const input: Input = { taxableIncome: 0 };
|
|
11
|
+
const service = new IsraelCorporateTaxServiceImpl(input, israelRules);
|
|
12
|
+
const result = service.calculate();
|
|
13
|
+
expect(result.corporateTax).toBe(0);
|
|
14
|
+
expect(result.effectiveTaxRate).toBe(0);
|
|
15
|
+
expect(result.breakdowns).toHaveLength(0);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('correctly applies the flat 23% rate', () => {
|
|
19
|
+
const input: Input = { taxableIncome: 100000 };
|
|
20
|
+
const service = new IsraelCorporateTaxServiceImpl(input, israelRules);
|
|
21
|
+
const result = service.calculate();
|
|
22
|
+
// 100000 * 0.23 = 23000
|
|
23
|
+
expect(result.corporateTax).toBe(23000);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('calculates effective tax rate as percentage', () => {
|
|
27
|
+
const input: Input = { taxableIncome: 100000 };
|
|
28
|
+
const service = new IsraelCorporateTaxServiceImpl(input, israelRules);
|
|
29
|
+
const result = service.calculate();
|
|
30
|
+
expect(result.effectiveTaxRate).toBe(23);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('returns one breakdown entry for flat rate calculation', () => {
|
|
34
|
+
const input: Input = { taxableIncome: 100000 };
|
|
35
|
+
const service = new IsraelCorporateTaxServiceImpl(input, israelRules);
|
|
36
|
+
const result = service.calculate();
|
|
37
|
+
expect(result.breakdowns).toHaveLength(1);
|
|
38
|
+
expect(result.breakdowns[0].rate).toBe(0.23);
|
|
39
|
+
expect(result.breakdowns[0].amount).toBe(23000);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('scales linearly with taxable income', () => {
|
|
43
|
+
const input: Input = { taxableIncome: 500000 };
|
|
44
|
+
const service = new IsraelCorporateTaxServiceImpl(input, israelRules);
|
|
45
|
+
const result = service.calculate();
|
|
46
|
+
expect(result.corporateTax).toBe(115000);
|
|
47
|
+
expect(result.effectiveTaxRate).toBe(23);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { IsraelIncomeTaxServiceImpl } from '../src/income-tax/israel/IsraelIncomeTaxServiceImpl';
|
|
2
|
+
import { IncomeTaxRules } from '../src/income-tax/israel/domain/types';
|
|
3
|
+
|
|
4
|
+
const israelRules: IncomeTaxRules = {
|
|
5
|
+
taxBrackets: [
|
|
6
|
+
{ from: 0, to: 81480, rate: 0.10 },
|
|
7
|
+
{ from: 81480, to: 116760, rate: 0.14 },
|
|
8
|
+
{ from: 116760, to: 187440, rate: 0.20 },
|
|
9
|
+
{ from: 187440, to: 260520, rate: 0.31 },
|
|
10
|
+
{ from: 260520, to: 542160, rate: 0.35 },
|
|
11
|
+
{ from: 542160, to: null, rate: 0.47 },
|
|
12
|
+
],
|
|
13
|
+
socialContributions: { rate: 0.12 },
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe('IsraelIncomeTaxServiceImpl', () => {
|
|
17
|
+
it('returns zero tax for zero income', () => {
|
|
18
|
+
const service = new IsraelIncomeTaxServiceImpl(0, israelRules);
|
|
19
|
+
const result = service.calculateNetIncome();
|
|
20
|
+
expect(result.incomeTax).toBe(0);
|
|
21
|
+
expect(result.socialContributions).toBe(0);
|
|
22
|
+
expect(result.totalDeductions).toBe(0);
|
|
23
|
+
expect(result.effectiveTaxRate).toBe(0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('correctly calculates income tax for income in first bracket', () => {
|
|
27
|
+
const service = new IsraelIncomeTaxServiceImpl(50000, israelRules);
|
|
28
|
+
const result = service.calculateNetIncome();
|
|
29
|
+
// 50000 * 0.10 = 5000
|
|
30
|
+
expect(result.incomeTax).toBeCloseTo(5000, 2);
|
|
31
|
+
expect(result.grossIncome).toBe(50000);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('correctly calculates social contributions', () => {
|
|
35
|
+
const service = new IsraelIncomeTaxServiceImpl(50000, israelRules);
|
|
36
|
+
const result = service.calculateNetIncome();
|
|
37
|
+
// 50000 * 0.12 = 6000
|
|
38
|
+
expect(result.socialContributions).toBeCloseTo(6000, 2);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('correctly calculates income tax spanning multiple brackets', () => {
|
|
42
|
+
const service = new IsraelIncomeTaxServiceImpl(120000, israelRules);
|
|
43
|
+
const result = service.calculateNetIncome();
|
|
44
|
+
// 0-81480: 81480 * 0.10 = 8148
|
|
45
|
+
// 81480-116760: 35280 * 0.14 = 4939.2
|
|
46
|
+
// 116760-120000: 3240 * 0.20 = 648
|
|
47
|
+
// Total = 13735.2
|
|
48
|
+
expect(result.incomeTax).toBeCloseTo(13735.2, 1);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('calculates effective tax rate as income tax divided by gross income', () => {
|
|
52
|
+
const service = new IsraelIncomeTaxServiceImpl(120000, israelRules);
|
|
53
|
+
const result = service.calculateNetIncome();
|
|
54
|
+
expect(result.effectiveTaxRate).toBeCloseTo(result.incomeTax / result.grossIncome, 4);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('net income equals gross income minus total deductions', () => {
|
|
58
|
+
const service = new IsraelIncomeTaxServiceImpl(120000, israelRules);
|
|
59
|
+
const result = service.calculateNetIncome();
|
|
60
|
+
expect(result.netIncome).toBeCloseTo(result.grossIncome - result.totalDeductions, 2);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('total deductions equals income tax plus social contributions', () => {
|
|
64
|
+
const service = new IsraelIncomeTaxServiceImpl(120000, israelRules);
|
|
65
|
+
const result = service.calculateNetIncome();
|
|
66
|
+
expect(result.totalDeductions).toBeCloseTo(result.incomeTax + result.socialContributions, 2);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('applies highest bracket rate to income above 542160', () => {
|
|
70
|
+
const service = new IsraelIncomeTaxServiceImpl(600000, israelRules);
|
|
71
|
+
const result = service.calculateNetIncome();
|
|
72
|
+
expect(result.incomeTax).toBeGreaterThan(0);
|
|
73
|
+
const lastBreakdown = result.taxBracketBreakdown[result.taxBracketBreakdown.length - 1];
|
|
74
|
+
expect(lastBreakdown.rate).toBe(0.47);
|
|
75
|
+
});
|
|
76
|
+
});
|