@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,101 @@
|
|
|
1
|
+
import { BrazilMortgageService } from "./BrazilMortgageService";
|
|
2
|
+
import { AmortizationScheduleItem, MortgageInput, MortgageOutput, MortgageRules } from "./domain/types";
|
|
3
|
+
|
|
4
|
+
export class BrazilMortgageServiceImpl implements BrazilMortgageService {
|
|
5
|
+
|
|
6
|
+
public calculate(input: MortgageInput, rules: MortgageRules): MortgageOutput {
|
|
7
|
+
const loanAmount = input.propertyPrice - input.downPayment;
|
|
8
|
+
|
|
9
|
+
if (loanAmount <= 0) {
|
|
10
|
+
throw new Error('Invalid loan amount: down payment must be less than property price');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const totalPayments = input.amortizationYears * 12;
|
|
14
|
+
const monthlyRate = (input.annualInterestRate / 100) / 12;
|
|
15
|
+
|
|
16
|
+
const monthlyPayment = this.calculatePayment(loanAmount, monthlyRate, totalPayments);
|
|
17
|
+
const totalPaid = monthlyPayment * totalPayments;
|
|
18
|
+
const totalInterestPaid = totalPaid - loanAmount;
|
|
19
|
+
const itbi = input.propertyPrice * rules.itbi.rate;
|
|
20
|
+
|
|
21
|
+
const amortizationSchedule = this.calculateAmortizationSchedule(
|
|
22
|
+
loanAmount,
|
|
23
|
+
monthlyRate,
|
|
24
|
+
monthlyPayment,
|
|
25
|
+
totalPayments,
|
|
26
|
+
input.amortizationYears,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
loanAmount,
|
|
31
|
+
totalMortgage: loanAmount,
|
|
32
|
+
monthlyPayment,
|
|
33
|
+
totalInterestPaid,
|
|
34
|
+
totalPaid,
|
|
35
|
+
itbi,
|
|
36
|
+
amortizationSchedule,
|
|
37
|
+
otherFees: {
|
|
38
|
+
notaryFees: {
|
|
39
|
+
value: itbi,
|
|
40
|
+
label: 'ITBI',
|
|
41
|
+
},
|
|
42
|
+
bankFees: {
|
|
43
|
+
value: 0,
|
|
44
|
+
label: 'BANK_FEES',
|
|
45
|
+
},
|
|
46
|
+
monthlyInsuranceFees: {
|
|
47
|
+
value: 0,
|
|
48
|
+
label: 'MONTHLY_INSURANCE_FEES',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private calculateAmortizationSchedule(
|
|
55
|
+
principal: number,
|
|
56
|
+
monthlyRate: number,
|
|
57
|
+
monthlyPayment: number,
|
|
58
|
+
totalPayments: number,
|
|
59
|
+
amortizationYears: number,
|
|
60
|
+
): AmortizationScheduleItem[] {
|
|
61
|
+
const schedule: AmortizationScheduleItem[] = [];
|
|
62
|
+
let balance = principal;
|
|
63
|
+
|
|
64
|
+
for (let year = 1; year <= amortizationYears; year++) {
|
|
65
|
+
let yearlyPrincipal = 0;
|
|
66
|
+
let yearlyInterest = 0;
|
|
67
|
+
|
|
68
|
+
const paymentsInYear = Math.min(12, totalPayments - (year - 1) * 12);
|
|
69
|
+
|
|
70
|
+
for (let payment = 1; payment <= paymentsInYear; payment++) {
|
|
71
|
+
const interestPayment = balance * monthlyRate;
|
|
72
|
+
const principalPayment = monthlyPayment - interestPayment;
|
|
73
|
+
|
|
74
|
+
yearlyInterest += interestPayment;
|
|
75
|
+
yearlyPrincipal += principalPayment;
|
|
76
|
+
balance -= principalPayment;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
schedule.push({
|
|
80
|
+
year,
|
|
81
|
+
principal: yearlyPrincipal,
|
|
82
|
+
interest: yearlyInterest,
|
|
83
|
+
balance: Math.max(0, balance),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (balance <= 0) break;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return schedule;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private calculatePayment(principal: number, rate: number, periods: number): number {
|
|
93
|
+
if (rate === 0) {
|
|
94
|
+
return principal / periods;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return principal *
|
|
98
|
+
(rate * Math.pow(1 + rate, periods)) /
|
|
99
|
+
(Math.pow(1 + rate, periods) - 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { OtherFees } from "../../domain/types";
|
|
2
|
+
|
|
3
|
+
export interface MortgageRules {
|
|
4
|
+
loanConstraints: LoanConstraints;
|
|
5
|
+
interest: InterestRules;
|
|
6
|
+
itbi: ITBIRules;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface LoanConstraints {
|
|
10
|
+
maxLtvPercent: number;
|
|
11
|
+
maxAmortizationYears: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface InterestRules {
|
|
15
|
+
compounding: 'MONTHLY';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ITBIRules {
|
|
19
|
+
rate: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface AmortizationScheduleItem {
|
|
23
|
+
year: number;
|
|
24
|
+
principal: number;
|
|
25
|
+
interest: number;
|
|
26
|
+
balance: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface MortgageInput {
|
|
30
|
+
propertyPrice: number;
|
|
31
|
+
downPayment: number;
|
|
32
|
+
annualInterestRate: number;
|
|
33
|
+
amortizationYears: number;
|
|
34
|
+
isFirstTimeBuyer: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface MortgageOutput {
|
|
38
|
+
loanAmount: number;
|
|
39
|
+
totalMortgage: number;
|
|
40
|
+
monthlyPayment: number;
|
|
41
|
+
totalInterestPaid: number;
|
|
42
|
+
totalPaid: number;
|
|
43
|
+
itbi: number;
|
|
44
|
+
amortizationSchedule: AmortizationScheduleItem[];
|
|
45
|
+
otherFees: OtherFees;
|
|
46
|
+
}
|
package/src/mortgage/index.ts
CHANGED
|
@@ -55,6 +55,62 @@ import {
|
|
|
55
55
|
MortgageOutput as GermanyMortgageOutput,
|
|
56
56
|
} from './germany/domain/types';
|
|
57
57
|
|
|
58
|
+
// Brazil
|
|
59
|
+
import { BrazilMortgageServiceImpl as BrazilMortgageService } from './brazil/BrazilMortgageServiceImpl';
|
|
60
|
+
import {
|
|
61
|
+
MortgageRules as BrazilMortgageRules,
|
|
62
|
+
MortgageInput as BrazilMortgageInput,
|
|
63
|
+
MortgageOutput as BrazilMortgageOutput,
|
|
64
|
+
} from './brazil/domain/types';
|
|
65
|
+
|
|
66
|
+
// Spain
|
|
67
|
+
import { SpainMortgageServiceImpl as SpainMortgageService } from './spain/SpainMortgageServiceImpl';
|
|
68
|
+
import {
|
|
69
|
+
MortgageRules as SpainMortgageRules,
|
|
70
|
+
MortgageInput as SpainMortgageInput,
|
|
71
|
+
MortgageOutput as SpainMortgageOutput,
|
|
72
|
+
} from './spain/domain/types';
|
|
73
|
+
|
|
74
|
+
// India
|
|
75
|
+
import { IndiaMortgageServiceImpl as IndiaMortgageService } from './india/IndiaMortgageServiceImpl';
|
|
76
|
+
import {
|
|
77
|
+
MortgageRules as IndiaMortgageRules,
|
|
78
|
+
MortgageInput as IndiaMortgageInput,
|
|
79
|
+
MortgageOutput as IndiaMortgageOutput,
|
|
80
|
+
} from './india/domain/types';
|
|
81
|
+
|
|
82
|
+
// Japan
|
|
83
|
+
import { JapanMortgageServiceImpl as JapanMortgageService } from './japan/JapanMortgageServiceImpl';
|
|
84
|
+
import {
|
|
85
|
+
MortgageRules as JapanMortgageRules,
|
|
86
|
+
MortgageInput as JapanMortgageInput,
|
|
87
|
+
MortgageOutput as JapanMortgageOutput,
|
|
88
|
+
} from './japan/domain/types';
|
|
89
|
+
|
|
90
|
+
// Israel
|
|
91
|
+
import { IsraelMortgageServiceImpl as IsraelMortgageService } from './israel/IsraelMortgageServiceImpl';
|
|
92
|
+
import {
|
|
93
|
+
MortgageRules as IsraelMortgageRules,
|
|
94
|
+
MortgageInput as IsraelMortgageInput,
|
|
95
|
+
MortgageOutput as IsraelMortgageOutput,
|
|
96
|
+
} from './israel/domain/types';
|
|
97
|
+
|
|
98
|
+
// Switzerland
|
|
99
|
+
import { SwitzerlandMortgageServiceImpl as SwitzerlandMortgageService } from './switzerland/SwitzerlandMortgageServiceImpl';
|
|
100
|
+
import {
|
|
101
|
+
MortgageRules as SwitzerlandMortgageRules,
|
|
102
|
+
MortgageInput as SwitzerlandMortgageInput,
|
|
103
|
+
MortgageOutput as SwitzerlandMortgageOutput,
|
|
104
|
+
} from './switzerland/domain/types';
|
|
105
|
+
|
|
106
|
+
// Netherlands
|
|
107
|
+
import { NetherlandsMortgageServiceImpl as NetherlandsMortgageService } from './netherlands/NetherlandsMortgageServiceImpl';
|
|
108
|
+
import {
|
|
109
|
+
MortgageRules as NetherlandsMortgageRules,
|
|
110
|
+
MortgageInput as NetherlandsMortgageInput,
|
|
111
|
+
MortgageOutput as NetherlandsMortgageOutput,
|
|
112
|
+
} from './netherlands/domain/types';
|
|
113
|
+
|
|
58
114
|
export {
|
|
59
115
|
CanadaMortgageService,
|
|
60
116
|
CanadaMortgageRules,
|
|
@@ -83,5 +139,33 @@ export {
|
|
|
83
139
|
GermanyMortgageService,
|
|
84
140
|
GermanyMortgageRules,
|
|
85
141
|
GermanyMortgageInput,
|
|
86
|
-
GermanyMortgageOutput
|
|
142
|
+
GermanyMortgageOutput,
|
|
143
|
+
BrazilMortgageService,
|
|
144
|
+
BrazilMortgageRules,
|
|
145
|
+
BrazilMortgageInput,
|
|
146
|
+
BrazilMortgageOutput,
|
|
147
|
+
SpainMortgageService,
|
|
148
|
+
SpainMortgageRules,
|
|
149
|
+
SpainMortgageInput,
|
|
150
|
+
SpainMortgageOutput,
|
|
151
|
+
IndiaMortgageService,
|
|
152
|
+
IndiaMortgageRules,
|
|
153
|
+
IndiaMortgageInput,
|
|
154
|
+
IndiaMortgageOutput,
|
|
155
|
+
JapanMortgageService,
|
|
156
|
+
JapanMortgageRules,
|
|
157
|
+
JapanMortgageInput,
|
|
158
|
+
JapanMortgageOutput,
|
|
159
|
+
IsraelMortgageService,
|
|
160
|
+
IsraelMortgageRules,
|
|
161
|
+
IsraelMortgageInput,
|
|
162
|
+
IsraelMortgageOutput,
|
|
163
|
+
SwitzerlandMortgageService,
|
|
164
|
+
SwitzerlandMortgageRules,
|
|
165
|
+
SwitzerlandMortgageInput,
|
|
166
|
+
SwitzerlandMortgageOutput,
|
|
167
|
+
NetherlandsMortgageService,
|
|
168
|
+
NetherlandsMortgageRules,
|
|
169
|
+
NetherlandsMortgageInput,
|
|
170
|
+
NetherlandsMortgageOutput,
|
|
87
171
|
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { IndiaMortgageService } from "./IndiaMortgageService";
|
|
2
|
+
import { AmortizationScheduleItem, MortgageInput, MortgageOutput, MortgageRules } from "./domain/types";
|
|
3
|
+
|
|
4
|
+
export class IndiaMortgageServiceImpl implements IndiaMortgageService {
|
|
5
|
+
|
|
6
|
+
public calculate(input: MortgageInput, rules: MortgageRules): MortgageOutput {
|
|
7
|
+
const loanAmount = input.propertyPrice - input.downPayment;
|
|
8
|
+
|
|
9
|
+
if (loanAmount <= 0) {
|
|
10
|
+
throw new Error('Invalid loan amount: down payment must be less than property price');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const totalPayments = input.amortizationYears * 12;
|
|
14
|
+
const monthlyRate = (input.annualInterestRate / 100) / 12;
|
|
15
|
+
|
|
16
|
+
const monthlyPayment = this.calculatePayment(loanAmount, monthlyRate, totalPayments);
|
|
17
|
+
const totalPaid = monthlyPayment * totalPayments;
|
|
18
|
+
const totalInterestPaid = totalPaid - loanAmount;
|
|
19
|
+
const stampDuty = input.propertyPrice * rules.stampDuty.rate;
|
|
20
|
+
|
|
21
|
+
const amortizationSchedule = this.calculateAmortizationSchedule(
|
|
22
|
+
loanAmount,
|
|
23
|
+
monthlyRate,
|
|
24
|
+
monthlyPayment,
|
|
25
|
+
totalPayments,
|
|
26
|
+
input.amortizationYears,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
loanAmount,
|
|
31
|
+
totalMortgage: loanAmount,
|
|
32
|
+
monthlyPayment,
|
|
33
|
+
totalInterestPaid,
|
|
34
|
+
totalPaid,
|
|
35
|
+
stampDuty,
|
|
36
|
+
amortizationSchedule,
|
|
37
|
+
otherFees: {
|
|
38
|
+
notaryFees: {
|
|
39
|
+
value: stampDuty,
|
|
40
|
+
label: 'STAMP_DUTY',
|
|
41
|
+
},
|
|
42
|
+
bankFees: {
|
|
43
|
+
value: 0,
|
|
44
|
+
label: 'BANK_FEES',
|
|
45
|
+
},
|
|
46
|
+
monthlyInsuranceFees: {
|
|
47
|
+
value: 0,
|
|
48
|
+
label: 'MONTHLY_INSURANCE_FEES',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private calculateAmortizationSchedule(
|
|
55
|
+
principal: number,
|
|
56
|
+
monthlyRate: number,
|
|
57
|
+
monthlyPayment: number,
|
|
58
|
+
totalPayments: number,
|
|
59
|
+
amortizationYears: number,
|
|
60
|
+
): AmortizationScheduleItem[] {
|
|
61
|
+
const schedule: AmortizationScheduleItem[] = [];
|
|
62
|
+
let balance = principal;
|
|
63
|
+
|
|
64
|
+
for (let year = 1; year <= amortizationYears; year++) {
|
|
65
|
+
let yearlyPrincipal = 0;
|
|
66
|
+
let yearlyInterest = 0;
|
|
67
|
+
|
|
68
|
+
const paymentsInYear = Math.min(12, totalPayments - (year - 1) * 12);
|
|
69
|
+
|
|
70
|
+
for (let payment = 1; payment <= paymentsInYear; payment++) {
|
|
71
|
+
const interestPayment = balance * monthlyRate;
|
|
72
|
+
const principalPayment = monthlyPayment - interestPayment;
|
|
73
|
+
|
|
74
|
+
yearlyInterest += interestPayment;
|
|
75
|
+
yearlyPrincipal += principalPayment;
|
|
76
|
+
balance -= principalPayment;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
schedule.push({
|
|
80
|
+
year,
|
|
81
|
+
principal: yearlyPrincipal,
|
|
82
|
+
interest: yearlyInterest,
|
|
83
|
+
balance: Math.max(0, balance),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (balance <= 0) break;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return schedule;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private calculatePayment(principal: number, rate: number, periods: number): number {
|
|
93
|
+
if (rate === 0) {
|
|
94
|
+
return principal / periods;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return principal *
|
|
98
|
+
(rate * Math.pow(1 + rate, periods)) /
|
|
99
|
+
(Math.pow(1 + rate, periods) - 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { OtherFees } from "../../domain/types";
|
|
2
|
+
|
|
3
|
+
export interface MortgageRules {
|
|
4
|
+
loanConstraints: LoanConstraints;
|
|
5
|
+
interest: InterestRules;
|
|
6
|
+
stampDuty: StampDutyRules;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface LoanConstraints {
|
|
10
|
+
maxLtvPercent: number;
|
|
11
|
+
maxAmortizationYears: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface InterestRules {
|
|
15
|
+
compounding: 'MONTHLY';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface StampDutyRules {
|
|
19
|
+
rate: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface AmortizationScheduleItem {
|
|
23
|
+
year: number;
|
|
24
|
+
principal: number;
|
|
25
|
+
interest: number;
|
|
26
|
+
balance: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface MortgageInput {
|
|
30
|
+
propertyPrice: number;
|
|
31
|
+
downPayment: number;
|
|
32
|
+
annualInterestRate: number;
|
|
33
|
+
amortizationYears: number;
|
|
34
|
+
isFirstTimeBuyer: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface MortgageOutput {
|
|
38
|
+
loanAmount: number;
|
|
39
|
+
totalMortgage: number;
|
|
40
|
+
monthlyPayment: number;
|
|
41
|
+
totalInterestPaid: number;
|
|
42
|
+
totalPaid: number;
|
|
43
|
+
stampDuty: number;
|
|
44
|
+
amortizationSchedule: AmortizationScheduleItem[];
|
|
45
|
+
otherFees: OtherFees;
|
|
46
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { IsraelMortgageService } from "./IsraelMortgageService";
|
|
2
|
+
import { AmortizationScheduleItem, MortgageInput, MortgageOutput, MortgageRules, PurchaseTaxBracket } from "./domain/types";
|
|
3
|
+
|
|
4
|
+
export class IsraelMortgageServiceImpl implements IsraelMortgageService {
|
|
5
|
+
|
|
6
|
+
public calculate(input: MortgageInput, rules: MortgageRules): MortgageOutput {
|
|
7
|
+
const loanAmount = input.propertyPrice - input.downPayment;
|
|
8
|
+
|
|
9
|
+
if (loanAmount <= 0) {
|
|
10
|
+
throw new Error('Invalid loan amount: down payment must be less than property price');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const totalPayments = input.amortizationYears * 12;
|
|
14
|
+
const monthlyRate = (input.annualInterestRate / 100) / 12;
|
|
15
|
+
|
|
16
|
+
const monthlyPayment = this.calculatePayment(loanAmount, monthlyRate, totalPayments);
|
|
17
|
+
const totalPaid = monthlyPayment * totalPayments;
|
|
18
|
+
const totalInterestPaid = totalPaid - loanAmount;
|
|
19
|
+
|
|
20
|
+
const purchaseTax = input.isFirstTimeBuyer
|
|
21
|
+
? this.calculatePurchaseTax(input.propertyPrice, rules.purchaseTax.brackets)
|
|
22
|
+
: input.propertyPrice * 0.08;
|
|
23
|
+
|
|
24
|
+
const landRegistrationFee = input.propertyPrice * rules.landRegistrationFeeRate;
|
|
25
|
+
|
|
26
|
+
const amortizationSchedule = this.calculateAmortizationSchedule(
|
|
27
|
+
loanAmount,
|
|
28
|
+
monthlyRate,
|
|
29
|
+
monthlyPayment,
|
|
30
|
+
totalPayments,
|
|
31
|
+
input.amortizationYears,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
loanAmount,
|
|
36
|
+
totalMortgage: loanAmount,
|
|
37
|
+
monthlyPayment,
|
|
38
|
+
totalInterestPaid,
|
|
39
|
+
totalPaid,
|
|
40
|
+
purchaseTax,
|
|
41
|
+
landRegistrationFee,
|
|
42
|
+
amortizationSchedule,
|
|
43
|
+
otherFees: {
|
|
44
|
+
notaryFees: {
|
|
45
|
+
value: purchaseTax,
|
|
46
|
+
label: 'PURCHASE_TAX',
|
|
47
|
+
},
|
|
48
|
+
bankFees: {
|
|
49
|
+
value: landRegistrationFee,
|
|
50
|
+
label: 'LAND_REGISTRATION_FEE',
|
|
51
|
+
},
|
|
52
|
+
monthlyInsuranceFees: {
|
|
53
|
+
value: 0,
|
|
54
|
+
label: 'MONTHLY_INSURANCE_FEES',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private calculatePurchaseTax(
|
|
61
|
+
propertyPrice: number,
|
|
62
|
+
brackets: PurchaseTaxBracket[],
|
|
63
|
+
): number {
|
|
64
|
+
let tax = 0;
|
|
65
|
+
let previousLimit = 0;
|
|
66
|
+
|
|
67
|
+
for (const bracket of brackets) {
|
|
68
|
+
if (bracket.upTo !== undefined) {
|
|
69
|
+
if (propertyPrice > previousLimit) {
|
|
70
|
+
const taxable = Math.min(propertyPrice, bracket.upTo) - previousLimit;
|
|
71
|
+
tax += taxable * bracket.rate;
|
|
72
|
+
previousLimit = bracket.upTo;
|
|
73
|
+
}
|
|
74
|
+
} else if (bracket.above !== undefined) {
|
|
75
|
+
if (propertyPrice > bracket.above) {
|
|
76
|
+
tax += (propertyPrice - bracket.above) * bracket.rate;
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return tax;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private calculateAmortizationSchedule(
|
|
86
|
+
principal: number,
|
|
87
|
+
monthlyRate: number,
|
|
88
|
+
monthlyPayment: number,
|
|
89
|
+
totalPayments: number,
|
|
90
|
+
amortizationYears: number,
|
|
91
|
+
): AmortizationScheduleItem[] {
|
|
92
|
+
const schedule: AmortizationScheduleItem[] = [];
|
|
93
|
+
let balance = principal;
|
|
94
|
+
|
|
95
|
+
for (let year = 1; year <= amortizationYears; year++) {
|
|
96
|
+
let yearlyPrincipal = 0;
|
|
97
|
+
let yearlyInterest = 0;
|
|
98
|
+
|
|
99
|
+
const paymentsInYear = Math.min(12, totalPayments - (year - 1) * 12);
|
|
100
|
+
|
|
101
|
+
for (let payment = 1; payment <= paymentsInYear; payment++) {
|
|
102
|
+
const interestPayment = balance * monthlyRate;
|
|
103
|
+
const principalPayment = monthlyPayment - interestPayment;
|
|
104
|
+
|
|
105
|
+
yearlyInterest += interestPayment;
|
|
106
|
+
yearlyPrincipal += principalPayment;
|
|
107
|
+
balance -= principalPayment;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
schedule.push({
|
|
111
|
+
year,
|
|
112
|
+
principal: yearlyPrincipal,
|
|
113
|
+
interest: yearlyInterest,
|
|
114
|
+
balance: Math.max(0, balance),
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
if (balance <= 0) break;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return schedule;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
private calculatePayment(principal: number, rate: number, periods: number): number {
|
|
124
|
+
if (rate === 0) {
|
|
125
|
+
return principal / periods;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return principal *
|
|
129
|
+
(rate * Math.pow(1 + rate, periods)) /
|
|
130
|
+
(Math.pow(1 + rate, periods) - 1);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { OtherFees } from "../../domain/types";
|
|
2
|
+
|
|
3
|
+
export interface PurchaseTaxBracket {
|
|
4
|
+
upTo?: number;
|
|
5
|
+
above?: number;
|
|
6
|
+
rate: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface MortgageRules {
|
|
10
|
+
loanConstraints: { maxLtvPercent: number; maxAmortizationYears: number };
|
|
11
|
+
interest: { compounding: 'MONTHLY' };
|
|
12
|
+
purchaseTax: { brackets: PurchaseTaxBracket[] };
|
|
13
|
+
landRegistrationFeeRate: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface AmortizationScheduleItem {
|
|
17
|
+
year: number;
|
|
18
|
+
principal: number;
|
|
19
|
+
interest: number;
|
|
20
|
+
balance: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface MortgageInput {
|
|
24
|
+
propertyPrice: number;
|
|
25
|
+
downPayment: number;
|
|
26
|
+
annualInterestRate: number;
|
|
27
|
+
amortizationYears: number;
|
|
28
|
+
isFirstTimeBuyer: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface MortgageOutput {
|
|
32
|
+
loanAmount: number;
|
|
33
|
+
totalMortgage: number;
|
|
34
|
+
monthlyPayment: number;
|
|
35
|
+
totalInterestPaid: number;
|
|
36
|
+
totalPaid: number;
|
|
37
|
+
purchaseTax: number;
|
|
38
|
+
landRegistrationFee: number;
|
|
39
|
+
amortizationSchedule: AmortizationScheduleItem[];
|
|
40
|
+
otherFees: OtherFees;
|
|
41
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { JapanMortgageService } from "./JapanMortgageService";
|
|
2
|
+
import { AmortizationScheduleItem, MortgageInput, MortgageOutput, MortgageRules } from "./domain/types";
|
|
3
|
+
|
|
4
|
+
export class JapanMortgageServiceImpl implements JapanMortgageService {
|
|
5
|
+
|
|
6
|
+
public calculate(input: MortgageInput, rules: MortgageRules): MortgageOutput {
|
|
7
|
+
const loanAmount = input.propertyPrice - input.downPayment;
|
|
8
|
+
|
|
9
|
+
if (loanAmount <= 0) {
|
|
10
|
+
throw new Error('Invalid loan amount: down payment must be less than property price');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const totalPayments = input.amortizationYears * 12;
|
|
14
|
+
const monthlyRate = (input.annualInterestRate / 100) / 12;
|
|
15
|
+
|
|
16
|
+
const monthlyPayment = this.calculatePayment(loanAmount, monthlyRate, totalPayments);
|
|
17
|
+
const totalPaid = monthlyPayment * totalPayments;
|
|
18
|
+
const totalInterestPaid = totalPaid - loanAmount;
|
|
19
|
+
const acquisitionTax = input.propertyPrice * rules.acquisitionTax.rate;
|
|
20
|
+
|
|
21
|
+
const amortizationSchedule = this.calculateAmortizationSchedule(
|
|
22
|
+
loanAmount,
|
|
23
|
+
monthlyRate,
|
|
24
|
+
monthlyPayment,
|
|
25
|
+
totalPayments,
|
|
26
|
+
input.amortizationYears,
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
loanAmount,
|
|
31
|
+
totalMortgage: loanAmount,
|
|
32
|
+
monthlyPayment,
|
|
33
|
+
totalInterestPaid,
|
|
34
|
+
totalPaid,
|
|
35
|
+
acquisitionTax,
|
|
36
|
+
amortizationSchedule,
|
|
37
|
+
otherFees: {
|
|
38
|
+
notaryFees: {
|
|
39
|
+
value: acquisitionTax,
|
|
40
|
+
label: 'ACQUISITION_TAX',
|
|
41
|
+
},
|
|
42
|
+
bankFees: {
|
|
43
|
+
value: 0,
|
|
44
|
+
label: 'BANK_FEES',
|
|
45
|
+
},
|
|
46
|
+
monthlyInsuranceFees: {
|
|
47
|
+
value: 0,
|
|
48
|
+
label: 'MONTHLY_INSURANCE_FEES',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private calculateAmortizationSchedule(
|
|
55
|
+
principal: number,
|
|
56
|
+
monthlyRate: number,
|
|
57
|
+
monthlyPayment: number,
|
|
58
|
+
totalPayments: number,
|
|
59
|
+
amortizationYears: number,
|
|
60
|
+
): AmortizationScheduleItem[] {
|
|
61
|
+
const schedule: AmortizationScheduleItem[] = [];
|
|
62
|
+
let balance = principal;
|
|
63
|
+
|
|
64
|
+
for (let year = 1; year <= amortizationYears; year++) {
|
|
65
|
+
let yearlyPrincipal = 0;
|
|
66
|
+
let yearlyInterest = 0;
|
|
67
|
+
|
|
68
|
+
const paymentsInYear = Math.min(12, totalPayments - (year - 1) * 12);
|
|
69
|
+
|
|
70
|
+
for (let payment = 1; payment <= paymentsInYear; payment++) {
|
|
71
|
+
const interestPayment = balance * monthlyRate;
|
|
72
|
+
const principalPayment = monthlyPayment - interestPayment;
|
|
73
|
+
|
|
74
|
+
yearlyInterest += interestPayment;
|
|
75
|
+
yearlyPrincipal += principalPayment;
|
|
76
|
+
balance -= principalPayment;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
schedule.push({
|
|
80
|
+
year,
|
|
81
|
+
principal: yearlyPrincipal,
|
|
82
|
+
interest: yearlyInterest,
|
|
83
|
+
balance: Math.max(0, balance),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (balance <= 0) break;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return schedule;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private calculatePayment(principal: number, rate: number, periods: number): number {
|
|
93
|
+
if (rate === 0) {
|
|
94
|
+
return principal / periods;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return principal *
|
|
98
|
+
(rate * Math.pow(1 + rate, periods)) /
|
|
99
|
+
(Math.pow(1 + rate, periods) - 1);
|
|
100
|
+
}
|
|
101
|
+
}
|