@novha/calc-engines 7.0.0 → 8.0.0

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.
Files changed (196) hide show
  1. package/dist/capital-gains/brazil/BrazilCapitalGainsService.js +3 -0
  2. package/dist/capital-gains/brazil/BrazilCapitalGainsServiceImpl.js +56 -0
  3. package/dist/capital-gains/brazil/domain/types.js +3 -0
  4. package/dist/capital-gains/index.js +14 -2
  5. package/dist/capital-gains/india/IndiaCapitalGainsService.js +3 -0
  6. package/dist/capital-gains/india/IndiaCapitalGainsServiceImpl.js +58 -0
  7. package/dist/capital-gains/india/domain/types.js +3 -0
  8. package/dist/capital-gains/japan/JapanCapitalGainsService.js +3 -0
  9. package/dist/capital-gains/japan/JapanCapitalGainsServiceImpl.js +41 -0
  10. package/dist/capital-gains/japan/domain/types.js +3 -0
  11. package/dist/capital-gains/spain/SpainCapitalGainsService.js +3 -0
  12. package/dist/capital-gains/spain/SpainCapitalGainsServiceImpl.js +56 -0
  13. package/dist/capital-gains/spain/domain/types.js +3 -0
  14. package/dist/corporate/brazil/BrazilCorporateTaxService.js +3 -0
  15. package/dist/corporate/brazil/BrazilCorporateTaxServiceImpl.js +33 -0
  16. package/dist/corporate/brazil/domain/types.js +3 -0
  17. package/dist/corporate/index.js +10 -2
  18. package/dist/corporate/india/IndiaCorporateTaxService.js +3 -0
  19. package/dist/corporate/india/IndiaCorporateTaxServiceImpl.js +29 -0
  20. package/dist/corporate/india/domain/types.js +3 -0
  21. package/dist/corporate/japan/JapanCorporateTaxService.js +3 -0
  22. package/dist/corporate/japan/JapanCorporateTaxServiceImpl.js +29 -0
  23. package/dist/corporate/japan/domain/types.js +3 -0
  24. package/dist/corporate/spain/SpainCorporateTaxService.js +3 -0
  25. package/dist/corporate/spain/SpainCorporateTaxServiceImpl.js +29 -0
  26. package/dist/corporate/spain/domain/types.js +3 -0
  27. package/dist/income-tax/brazil/BrazilIncomeTaxService.js +3 -0
  28. package/dist/income-tax/brazil/BrazilIncomeTaxServiceImpl.js +78 -0
  29. package/dist/income-tax/brazil/domain/types.js +3 -0
  30. package/dist/income-tax/index.js +14 -2
  31. package/dist/income-tax/india/IndiaIncomeTaxService.js +3 -0
  32. package/dist/income-tax/india/IndiaIncomeTaxServiceImpl.js +75 -0
  33. package/dist/income-tax/india/domain/types.js +3 -0
  34. package/dist/income-tax/japan/JapanIncomeTaxService.js +3 -0
  35. package/dist/income-tax/japan/JapanIncomeTaxServiceImpl.js +75 -0
  36. package/dist/income-tax/japan/domain/types.js +3 -0
  37. package/dist/income-tax/spain/SpainIncomeTaxService.js +3 -0
  38. package/dist/income-tax/spain/SpainIncomeTaxServiceImpl.js +62 -0
  39. package/dist/income-tax/spain/domain/types.js +3 -0
  40. package/dist/inheritance-tax/index.js +8 -2
  41. package/dist/inheritance-tax/japan/JapanInheritanceTaxService.js +3 -0
  42. package/dist/inheritance-tax/japan/JapanInheritanceTaxServiceImpl.js +53 -0
  43. package/dist/inheritance-tax/japan/domain/types.js +3 -0
  44. package/dist/inheritance-tax/spain/SpainInheritanceTaxService.js +3 -0
  45. package/dist/inheritance-tax/spain/SpainInheritanceTaxServiceImpl.js +51 -0
  46. package/dist/inheritance-tax/spain/domain/types.js +3 -0
  47. package/dist/mortgage/brazil/BrazilMortgageService.js +3 -0
  48. package/dist/mortgage/brazil/BrazilMortgageServiceImpl.js +76 -0
  49. package/dist/mortgage/brazil/domain/types.js +3 -0
  50. package/dist/mortgage/index.js +14 -2
  51. package/dist/mortgage/india/IndiaMortgageService.js +3 -0
  52. package/dist/mortgage/india/IndiaMortgageServiceImpl.js +76 -0
  53. package/dist/mortgage/india/domain/types.js +3 -0
  54. package/dist/mortgage/japan/JapanMortgageService.js +3 -0
  55. package/dist/mortgage/japan/JapanMortgageServiceImpl.js +76 -0
  56. package/dist/mortgage/japan/domain/types.js +3 -0
  57. package/dist/mortgage/spain/SpainMortgageService.js +3 -0
  58. package/dist/mortgage/spain/SpainMortgageServiceImpl.js +96 -0
  59. package/dist/mortgage/spain/domain/types.js +3 -0
  60. package/dist/types/capital-gains/brazil/BrazilCapitalGainsService.d.ts +4 -0
  61. package/dist/types/capital-gains/brazil/BrazilCapitalGainsServiceImpl.d.ts +10 -0
  62. package/dist/types/capital-gains/brazil/domain/types.d.ts +11 -0
  63. package/dist/types/capital-gains/index.d.ts +9 -1
  64. package/dist/types/capital-gains/india/IndiaCapitalGainsService.d.ts +4 -0
  65. package/dist/types/capital-gains/india/IndiaCapitalGainsServiceImpl.d.ts +9 -0
  66. package/dist/types/capital-gains/india/domain/types.d.ts +9 -0
  67. package/dist/types/capital-gains/japan/JapanCapitalGainsService.d.ts +4 -0
  68. package/dist/types/capital-gains/japan/JapanCapitalGainsServiceImpl.d.ts +9 -0
  69. package/dist/types/capital-gains/japan/domain/types.d.ts +6 -0
  70. package/dist/types/capital-gains/spain/SpainCapitalGainsService.d.ts +4 -0
  71. package/dist/types/capital-gains/spain/SpainCapitalGainsServiceImpl.d.ts +10 -0
  72. package/dist/types/capital-gains/spain/domain/types.d.ts +11 -0
  73. package/dist/types/corporate/brazil/BrazilCorporateTaxService.d.ts +4 -0
  74. package/dist/types/corporate/brazil/BrazilCorporateTaxServiceImpl.d.ts +8 -0
  75. package/dist/types/corporate/brazil/domain/types.d.ts +19 -0
  76. package/dist/types/corporate/index.d.ts +9 -1
  77. package/dist/types/corporate/india/IndiaCorporateTaxService.d.ts +4 -0
  78. package/dist/types/corporate/india/IndiaCorporateTaxServiceImpl.d.ts +8 -0
  79. package/dist/types/corporate/india/domain/types.d.ts +15 -0
  80. package/dist/types/corporate/japan/JapanCorporateTaxService.d.ts +4 -0
  81. package/dist/types/corporate/japan/JapanCorporateTaxServiceImpl.d.ts +8 -0
  82. package/dist/types/corporate/japan/domain/types.d.ts +15 -0
  83. package/dist/types/corporate/spain/SpainCorporateTaxService.d.ts +4 -0
  84. package/dist/types/corporate/spain/SpainCorporateTaxServiceImpl.d.ts +8 -0
  85. package/dist/types/corporate/spain/domain/types.d.ts +15 -0
  86. package/dist/types/income-tax/brazil/BrazilIncomeTaxService.d.ts +4 -0
  87. package/dist/types/income-tax/brazil/BrazilIncomeTaxServiceImpl.d.ts +11 -0
  88. package/dist/types/income-tax/brazil/domain/types.d.ts +18 -0
  89. package/dist/types/income-tax/index.d.ts +9 -1
  90. package/dist/types/income-tax/india/IndiaIncomeTaxService.d.ts +4 -0
  91. package/dist/types/income-tax/india/IndiaIncomeTaxServiceImpl.d.ts +10 -0
  92. package/dist/types/income-tax/india/domain/types.d.ts +16 -0
  93. package/dist/types/income-tax/japan/JapanIncomeTaxService.d.ts +4 -0
  94. package/dist/types/income-tax/japan/JapanIncomeTaxServiceImpl.d.ts +10 -0
  95. package/dist/types/income-tax/japan/domain/types.d.ts +16 -0
  96. package/dist/types/income-tax/spain/SpainIncomeTaxService.d.ts +4 -0
  97. package/dist/types/income-tax/spain/SpainIncomeTaxServiceImpl.d.ts +10 -0
  98. package/dist/types/income-tax/spain/domain/types.d.ts +16 -0
  99. package/dist/types/inheritance-tax/index.d.ts +5 -1
  100. package/dist/types/inheritance-tax/japan/JapanInheritanceTaxService.d.ts +4 -0
  101. package/dist/types/inheritance-tax/japan/JapanInheritanceTaxServiceImpl.d.ts +9 -0
  102. package/dist/types/inheritance-tax/japan/domain/types.d.ts +21 -0
  103. package/dist/types/inheritance-tax/spain/SpainInheritanceTaxService.d.ts +4 -0
  104. package/dist/types/inheritance-tax/spain/SpainInheritanceTaxServiceImpl.d.ts +9 -0
  105. package/dist/types/inheritance-tax/spain/domain/types.d.ts +19 -0
  106. package/dist/types/mortgage/brazil/BrazilMortgageService.d.ts +4 -0
  107. package/dist/types/mortgage/brazil/BrazilMortgageServiceImpl.d.ts +7 -0
  108. package/dist/types/mortgage/brazil/domain/types.d.ts +39 -0
  109. package/dist/types/mortgage/index.d.ts +9 -1
  110. package/dist/types/mortgage/india/IndiaMortgageService.d.ts +4 -0
  111. package/dist/types/mortgage/india/IndiaMortgageServiceImpl.d.ts +7 -0
  112. package/dist/types/mortgage/india/domain/types.d.ts +39 -0
  113. package/dist/types/mortgage/japan/JapanMortgageService.d.ts +4 -0
  114. package/dist/types/mortgage/japan/JapanMortgageServiceImpl.d.ts +7 -0
  115. package/dist/types/mortgage/japan/domain/types.d.ts +39 -0
  116. package/dist/types/mortgage/spain/SpainMortgageService.d.ts +4 -0
  117. package/dist/types/mortgage/spain/SpainMortgageServiceImpl.d.ts +8 -0
  118. package/dist/types/mortgage/spain/domain/types.d.ts +44 -0
  119. package/package.json +1 -1
  120. package/src/capital-gains/brazil/BrazilCapitalGainsService.ts +5 -0
  121. package/src/capital-gains/brazil/BrazilCapitalGainsServiceImpl.ts +69 -0
  122. package/src/capital-gains/brazil/domain/types.ts +15 -0
  123. package/src/capital-gains/index.ts +40 -0
  124. package/src/capital-gains/india/IndiaCapitalGainsService.ts +5 -0
  125. package/src/capital-gains/india/IndiaCapitalGainsServiceImpl.ts +64 -0
  126. package/src/capital-gains/india/domain/types.ts +12 -0
  127. package/src/capital-gains/japan/JapanCapitalGainsService.ts +5 -0
  128. package/src/capital-gains/japan/JapanCapitalGainsServiceImpl.ts +47 -0
  129. package/src/capital-gains/japan/domain/types.ts +9 -0
  130. package/src/capital-gains/spain/SpainCapitalGainsService.ts +5 -0
  131. package/src/capital-gains/spain/SpainCapitalGainsServiceImpl.ts +69 -0
  132. package/src/capital-gains/spain/domain/types.ts +15 -0
  133. package/src/corporate/brazil/BrazilCorporateTaxService.ts +5 -0
  134. package/src/corporate/brazil/BrazilCorporateTaxServiceImpl.ts +40 -0
  135. package/src/corporate/brazil/domain/types.ts +16 -0
  136. package/src/corporate/index.ts +45 -1
  137. package/src/corporate/india/IndiaCorporateTaxService.ts +5 -0
  138. package/src/corporate/india/IndiaCorporateTaxServiceImpl.ts +35 -0
  139. package/src/corporate/india/domain/types.ts +15 -0
  140. package/src/corporate/japan/JapanCorporateTaxService.ts +5 -0
  141. package/src/corporate/japan/JapanCorporateTaxServiceImpl.ts +35 -0
  142. package/src/corporate/japan/domain/types.ts +15 -0
  143. package/src/corporate/spain/SpainCorporateTaxService.ts +5 -0
  144. package/src/corporate/spain/SpainCorporateTaxServiceImpl.ts +35 -0
  145. package/src/corporate/spain/domain/types.ts +15 -0
  146. package/src/income-tax/brazil/BrazilIncomeTaxService.ts +5 -0
  147. package/src/income-tax/brazil/BrazilIncomeTaxServiceImpl.ts +91 -0
  148. package/src/income-tax/brazil/domain/types.ts +21 -0
  149. package/src/income-tax/index.ts +40 -0
  150. package/src/income-tax/india/IndiaIncomeTaxService.ts +5 -0
  151. package/src/income-tax/india/IndiaIncomeTaxServiceImpl.ts +87 -0
  152. package/src/income-tax/india/domain/types.ts +16 -0
  153. package/src/income-tax/japan/JapanIncomeTaxService.ts +5 -0
  154. package/src/income-tax/japan/JapanIncomeTaxServiceImpl.ts +87 -0
  155. package/src/income-tax/japan/domain/types.ts +16 -0
  156. package/src/income-tax/spain/SpainIncomeTaxService.ts +5 -0
  157. package/src/income-tax/spain/SpainIncomeTaxServiceImpl.ts +75 -0
  158. package/src/income-tax/spain/domain/types.ts +16 -0
  159. package/src/inheritance-tax/index.ts +24 -0
  160. package/src/inheritance-tax/japan/JapanInheritanceTaxService.ts +5 -0
  161. package/src/inheritance-tax/japan/JapanInheritanceTaxServiceImpl.ts +67 -0
  162. package/src/inheritance-tax/japan/domain/types.ts +25 -0
  163. package/src/inheritance-tax/spain/SpainInheritanceTaxService.ts +5 -0
  164. package/src/inheritance-tax/spain/SpainInheritanceTaxServiceImpl.ts +65 -0
  165. package/src/inheritance-tax/spain/domain/types.ts +23 -0
  166. package/src/mortgage/brazil/BrazilMortgageService.ts +5 -0
  167. package/src/mortgage/brazil/BrazilMortgageServiceImpl.ts +101 -0
  168. package/src/mortgage/brazil/domain/types.ts +46 -0
  169. package/src/mortgage/index.ts +49 -1
  170. package/src/mortgage/india/IndiaMortgageService.ts +5 -0
  171. package/src/mortgage/india/IndiaMortgageServiceImpl.ts +101 -0
  172. package/src/mortgage/india/domain/types.ts +46 -0
  173. package/src/mortgage/japan/JapanMortgageService.ts +5 -0
  174. package/src/mortgage/japan/JapanMortgageServiceImpl.ts +101 -0
  175. package/src/mortgage/japan/domain/types.ts +46 -0
  176. package/src/mortgage/spain/SpainMortgageService.ts +5 -0
  177. package/src/mortgage/spain/SpainMortgageServiceImpl.ts +130 -0
  178. package/src/mortgage/spain/domain/types.ts +52 -0
  179. package/test/brazil-capital-gains.test.ts +65 -0
  180. package/test/brazil-corporate-tax.test.ts +63 -0
  181. package/test/brazil-income-tax.test.ts +85 -0
  182. package/test/brazil-mortgage.test.ts +70 -0
  183. package/test/india-capital-gains.test.ts +71 -0
  184. package/test/india-corporate-tax.test.ts +54 -0
  185. package/test/india-income-tax.test.ts +78 -0
  186. package/test/india-mortgage.test.ts +70 -0
  187. package/test/japan-capital-gains.test.ts +55 -0
  188. package/test/japan-corporate-tax.test.ts +54 -0
  189. package/test/japan-income-tax.test.ts +76 -0
  190. package/test/japan-inheritance-tax.test.ts +74 -0
  191. package/test/japan-mortgage.test.ts +69 -0
  192. package/test/spain-capital-gains.test.ts +66 -0
  193. package/test/spain-corporate-tax.test.ts +54 -0
  194. package/test/spain-income-tax.test.ts +84 -0
  195. package/test/spain-inheritance-tax.test.ts +78 -0
  196. package/test/spain-mortgage.test.ts +70 -0
@@ -0,0 +1,5 @@
1
+ import { Result } from "./domain/types";
2
+
3
+ export interface JapanCorporateTaxService {
4
+ calculate(): Result;
5
+ }
@@ -0,0 +1,35 @@
1
+ import { Breakdown } from "../domain/types";
2
+ import { JapanCorporateTaxService } from "./JapanCorporateTaxService";
3
+ import { Input, Result, Rules } from "./domain/types";
4
+
5
+ export class JapanCorporateTaxServiceImpl implements JapanCorporateTaxService {
6
+ private _input: Input;
7
+ private _rules: Rules;
8
+
9
+ constructor(input: Input, rules: Rules) {
10
+ this._input = input;
11
+ this._rules = rules;
12
+ }
13
+
14
+ calculate(): Result {
15
+ const income = this._input.taxableIncome;
16
+
17
+ if (income <= 0) {
18
+ return { corporateTax: 0, effectiveTaxRate: 0, breakdowns: [] };
19
+ }
20
+
21
+ const tax = income * this._rules.regime.rate;
22
+ const breakdowns: Breakdown[] = [{
23
+ from: '0',
24
+ to: 'All',
25
+ rate: this._rules.regime.rate,
26
+ amount: tax,
27
+ }];
28
+
29
+ return {
30
+ corporateTax: tax,
31
+ effectiveTaxRate: (tax / income) * 100,
32
+ breakdowns,
33
+ };
34
+ }
35
+ }
@@ -0,0 +1,15 @@
1
+ import { Breakdown } from "../../domain/types";
2
+
3
+ export interface Rules {
4
+ regime: { type: 'flat'; rate: number };
5
+ }
6
+
7
+ export interface Input {
8
+ taxableIncome: number;
9
+ }
10
+
11
+ export interface Result {
12
+ corporateTax: number;
13
+ effectiveTaxRate: number;
14
+ breakdowns: Breakdown[];
15
+ }
@@ -0,0 +1,5 @@
1
+ import { Result } from "./domain/types";
2
+
3
+ export interface SpainCorporateTaxService {
4
+ calculate(): Result;
5
+ }
@@ -0,0 +1,35 @@
1
+ import { Breakdown } from "../domain/types";
2
+ import { SpainCorporateTaxService } from "./SpainCorporateTaxService";
3
+ import { Input, Result, Rules } from "./domain/types";
4
+
5
+ export class SpainCorporateTaxServiceImpl implements SpainCorporateTaxService {
6
+ private _input: Input;
7
+ private _rules: Rules;
8
+
9
+ constructor(input: Input, rules: Rules) {
10
+ this._input = input;
11
+ this._rules = rules;
12
+ }
13
+
14
+ calculate(): Result {
15
+ const income = this._input.taxableIncome;
16
+
17
+ if (income <= 0) {
18
+ return { corporateTax: 0, effectiveTaxRate: 0, breakdowns: [] };
19
+ }
20
+
21
+ const tax = income * this._rules.regime.rate;
22
+ const breakdowns: Breakdown[] = [{
23
+ from: '0',
24
+ to: 'All',
25
+ rate: this._rules.regime.rate,
26
+ amount: tax,
27
+ }];
28
+
29
+ return {
30
+ corporateTax: tax,
31
+ effectiveTaxRate: (tax / income) * 100,
32
+ breakdowns,
33
+ };
34
+ }
35
+ }
@@ -0,0 +1,15 @@
1
+ import { Breakdown } from "../../domain/types";
2
+
3
+ export interface Rules {
4
+ regime: { type: 'flat'; rate: number };
5
+ }
6
+
7
+ export interface Input {
8
+ taxableIncome: number;
9
+ }
10
+
11
+ export interface Result {
12
+ corporateTax: number;
13
+ effectiveTaxRate: number;
14
+ breakdowns: Breakdown[];
15
+ }
@@ -0,0 +1,5 @@
1
+ import { ComputedIncomeTaxValues } from "./domain/types";
2
+
3
+ export interface BrazilIncomeTaxService {
4
+ calculateNetIncome(): ComputedIncomeTaxValues;
5
+ }
@@ -0,0 +1,91 @@
1
+ import { BracketAllocation } from "../domain/types";
2
+ import { BrazilIncomeTaxService } from "./BrazilIncomeTaxService";
3
+ import { ComputedIncomeTaxValues, INSSRules, IncomeTaxRules } from "./domain/types";
4
+
5
+ export class BrazilIncomeTaxServiceImpl implements BrazilIncomeTaxService {
6
+ private _income: number;
7
+ private _rules: IncomeTaxRules;
8
+
9
+ constructor(income: number, rules: IncomeTaxRules) {
10
+ this._income = income;
11
+ this._rules = rules;
12
+ }
13
+
14
+ public calculateNetIncome(): ComputedIncomeTaxValues {
15
+ const { grossTax, bracketBreakdown } = this.computeTaxBrackets(this._income);
16
+ const inss = this.computeINSS(this._income, this._rules.inss);
17
+ const totalDeductions = grossTax + inss;
18
+ const netIncome = this._income - totalDeductions;
19
+
20
+ return {
21
+ grossIncome: this._income,
22
+ incomeTax: this.round(grossTax),
23
+ inss: this.round(inss),
24
+ totalDeductions: this.round(totalDeductions),
25
+ netIncome: this.round(netIncome),
26
+ effectiveTaxRate: this._income > 0 ? this.round(grossTax / this._income, 4) : 0,
27
+ taxBracketBreakdown: bracketBreakdown,
28
+ };
29
+ }
30
+
31
+ private computeTaxBrackets(
32
+ income: number,
33
+ ): { grossTax: number; bracketBreakdown: BracketAllocation[] } {
34
+ let tax = 0;
35
+ const bracketBreakdown: BracketAllocation[] = [];
36
+
37
+ for (let index = 0; index < this._rules.taxBrackets.length; index++) {
38
+ const bracket = this._rules.taxBrackets[index];
39
+
40
+ if (income <= bracket.from) {
41
+ bracketBreakdown.push({
42
+ bracketIndex: index,
43
+ bracketName: `Bracket ${index + 1}`,
44
+ from: bracket.from,
45
+ to: bracket.to ?? null,
46
+ rate: bracket.rate,
47
+ amountInBracket: 0,
48
+ taxOnAmount: 0,
49
+ });
50
+ break;
51
+ }
52
+
53
+ const upper = bracket.to ?? income;
54
+ const taxableAmount = Math.min(upper, income) - bracket.from;
55
+
56
+ if (taxableAmount > 0) {
57
+ const taxOnAmount = taxableAmount * bracket.rate;
58
+ tax += taxOnAmount;
59
+ bracketBreakdown.push({
60
+ bracketIndex: index,
61
+ bracketName: `Bracket ${index + 1}`,
62
+ from: bracket.from,
63
+ to: bracket.to ?? null,
64
+ rate: bracket.rate,
65
+ amountInBracket: taxableAmount,
66
+ taxOnAmount,
67
+ });
68
+ } else {
69
+ bracketBreakdown.push({
70
+ bracketIndex: index,
71
+ bracketName: `Bracket ${index + 1}`,
72
+ from: bracket.from,
73
+ to: bracket.to ?? null,
74
+ rate: bracket.rate,
75
+ amountInBracket: 0,
76
+ taxOnAmount: 0,
77
+ });
78
+ }
79
+ }
80
+
81
+ return { grossTax: tax, bracketBreakdown };
82
+ }
83
+
84
+ private computeINSS(income: number, rules: INSSRules): number {
85
+ return Math.min(income, rules.cap) * rules.rate;
86
+ }
87
+
88
+ private round(value: number, decimals = 2): number {
89
+ return Number(value.toFixed(decimals));
90
+ }
91
+ }
@@ -0,0 +1,21 @@
1
+ import { BracketAllocation, TaxBracket } from "../../domain/types";
2
+
3
+ export interface IncomeTaxRules {
4
+ taxBrackets: TaxBracket[];
5
+ inss: INSSRules;
6
+ }
7
+
8
+ export interface INSSRules {
9
+ rate: number;
10
+ cap: number;
11
+ }
12
+
13
+ export interface ComputedIncomeTaxValues {
14
+ grossIncome: number;
15
+ incomeTax: number;
16
+ inss: number;
17
+ totalDeductions: number;
18
+ netIncome: number;
19
+ effectiveTaxRate: number;
20
+ taxBracketBreakdown: BracketAllocation[];
21
+ }
@@ -47,6 +47,34 @@ import {
47
47
  IncomeTaxRules as GermanyIncomeTaxRules,
48
48
  } from './germany/domain/types';
49
49
 
50
+ // Brazil
51
+ import { BrazilIncomeTaxServiceImpl as BrazilIncomeTaxService } from './brazil/BrazilIncomeTaxServiceImpl';
52
+ import {
53
+ ComputedIncomeTaxValues as BrazilComputedIncomeTaxValues,
54
+ IncomeTaxRules as BrazilIncomeTaxRules,
55
+ } from './brazil/domain/types';
56
+
57
+ // Spain
58
+ import { SpainIncomeTaxServiceImpl as SpainIncomeTaxService } from './spain/SpainIncomeTaxServiceImpl';
59
+ import {
60
+ ComputedIncomeTaxValues as SpainComputedIncomeTaxValues,
61
+ IncomeTaxRules as SpainIncomeTaxRules,
62
+ } from './spain/domain/types';
63
+
64
+ // India
65
+ import { IndiaIncomeTaxServiceImpl as IndiaIncomeTaxService } from './india/IndiaIncomeTaxServiceImpl';
66
+ import {
67
+ ComputedIncomeTaxValues as IndiaComputedIncomeTaxValues,
68
+ IncomeTaxRules as IndiaIncomeTaxRules,
69
+ } from './india/domain/types';
70
+
71
+ // Japan
72
+ import { JapanIncomeTaxServiceImpl as JapanIncomeTaxService } from './japan/JapanIncomeTaxServiceImpl';
73
+ import {
74
+ ComputedIncomeTaxValues as JapanComputedIncomeTaxValues,
75
+ IncomeTaxRules as JapanIncomeTaxRules,
76
+ } from './japan/domain/types';
77
+
50
78
  export {
51
79
  CanadaIncomeTaxService,
52
80
  CanadaComputedIncomeTaxValues,
@@ -69,4 +97,16 @@ export {
69
97
  GermanyIncomeTaxService,
70
98
  GermanyComputedIncomeTaxValues,
71
99
  GermanyIncomeTaxRules,
100
+ BrazilIncomeTaxService,
101
+ BrazilComputedIncomeTaxValues,
102
+ BrazilIncomeTaxRules,
103
+ SpainIncomeTaxService,
104
+ SpainComputedIncomeTaxValues,
105
+ SpainIncomeTaxRules,
106
+ IndiaIncomeTaxService,
107
+ IndiaComputedIncomeTaxValues,
108
+ IndiaIncomeTaxRules,
109
+ JapanIncomeTaxService,
110
+ JapanComputedIncomeTaxValues,
111
+ JapanIncomeTaxRules,
72
112
  };
@@ -0,0 +1,5 @@
1
+ import { ComputedIncomeTaxValues } from "./domain/types";
2
+
3
+ export interface IndiaIncomeTaxService {
4
+ calculateNetIncome(): ComputedIncomeTaxValues;
5
+ }
@@ -0,0 +1,87 @@
1
+ import { BracketAllocation } from "../domain/types";
2
+ import { IndiaIncomeTaxService } from "./IndiaIncomeTaxService";
3
+ import { ComputedIncomeTaxValues, IncomeTaxRules } from "./domain/types";
4
+
5
+ export class IndiaIncomeTaxServiceImpl implements IndiaIncomeTaxService {
6
+ private _income: number;
7
+ private _rules: IncomeTaxRules;
8
+
9
+ constructor(income: number, rules: IncomeTaxRules) {
10
+ this._income = income;
11
+ this._rules = rules;
12
+ }
13
+
14
+ public calculateNetIncome(): ComputedIncomeTaxValues {
15
+ const { grossTax, bracketBreakdown } = this.computeTaxBrackets(this._income);
16
+ const cess = grossTax * this._rules.cess.rate;
17
+ const totalDeductions = grossTax + cess;
18
+ const netIncome = this._income - totalDeductions;
19
+
20
+ return {
21
+ grossIncome: this._income,
22
+ incomeTax: this.round(grossTax),
23
+ cess: this.round(cess),
24
+ totalDeductions: this.round(totalDeductions),
25
+ netIncome: this.round(netIncome),
26
+ effectiveTaxRate: this._income > 0 ? this.round(grossTax / this._income, 4) : 0,
27
+ taxBracketBreakdown: bracketBreakdown,
28
+ };
29
+ }
30
+
31
+ private computeTaxBrackets(
32
+ income: number,
33
+ ): { grossTax: number; bracketBreakdown: BracketAllocation[] } {
34
+ let tax = 0;
35
+ const bracketBreakdown: BracketAllocation[] = [];
36
+
37
+ for (let index = 0; index < this._rules.taxBrackets.length; index++) {
38
+ const bracket = this._rules.taxBrackets[index];
39
+
40
+ if (income <= bracket.from) {
41
+ bracketBreakdown.push({
42
+ bracketIndex: index,
43
+ bracketName: `Bracket ${index + 1}`,
44
+ from: bracket.from,
45
+ to: bracket.to ?? null,
46
+ rate: bracket.rate,
47
+ amountInBracket: 0,
48
+ taxOnAmount: 0,
49
+ });
50
+ break;
51
+ }
52
+
53
+ const upper = bracket.to ?? income;
54
+ const taxableAmount = Math.min(upper, income) - bracket.from;
55
+
56
+ if (taxableAmount > 0) {
57
+ const taxOnAmount = taxableAmount * bracket.rate;
58
+ tax += taxOnAmount;
59
+ bracketBreakdown.push({
60
+ bracketIndex: index,
61
+ bracketName: `Bracket ${index + 1}`,
62
+ from: bracket.from,
63
+ to: bracket.to ?? null,
64
+ rate: bracket.rate,
65
+ amountInBracket: taxableAmount,
66
+ taxOnAmount,
67
+ });
68
+ } else {
69
+ bracketBreakdown.push({
70
+ bracketIndex: index,
71
+ bracketName: `Bracket ${index + 1}`,
72
+ from: bracket.from,
73
+ to: bracket.to ?? null,
74
+ rate: bracket.rate,
75
+ amountInBracket: 0,
76
+ taxOnAmount: 0,
77
+ });
78
+ }
79
+ }
80
+
81
+ return { grossTax: tax, bracketBreakdown };
82
+ }
83
+
84
+ private round(value: number, decimals = 2): number {
85
+ return Number(value.toFixed(decimals));
86
+ }
87
+ }
@@ -0,0 +1,16 @@
1
+ import { BracketAllocation, TaxBracket } from "../../domain/types";
2
+
3
+ export interface IncomeTaxRules {
4
+ taxBrackets: TaxBracket[];
5
+ cess: { rate: number };
6
+ }
7
+
8
+ export interface ComputedIncomeTaxValues {
9
+ grossIncome: number;
10
+ incomeTax: number;
11
+ cess: number;
12
+ totalDeductions: number;
13
+ netIncome: number;
14
+ effectiveTaxRate: number;
15
+ taxBracketBreakdown: BracketAllocation[];
16
+ }
@@ -0,0 +1,5 @@
1
+ import { ComputedIncomeTaxValues } from "./domain/types";
2
+
3
+ export interface JapanIncomeTaxService {
4
+ calculateNetIncome(): ComputedIncomeTaxValues;
5
+ }
@@ -0,0 +1,87 @@
1
+ import { BracketAllocation } from "../domain/types";
2
+ import { JapanIncomeTaxService } from "./JapanIncomeTaxService";
3
+ import { ComputedIncomeTaxValues, IncomeTaxRules } from "./domain/types";
4
+
5
+ export class JapanIncomeTaxServiceImpl implements JapanIncomeTaxService {
6
+ private _income: number;
7
+ private _rules: IncomeTaxRules;
8
+
9
+ constructor(income: number, rules: IncomeTaxRules) {
10
+ this._income = income;
11
+ this._rules = rules;
12
+ }
13
+
14
+ public calculateNetIncome(): ComputedIncomeTaxValues {
15
+ const { grossTax, bracketBreakdown } = this.computeTaxBrackets(this._income);
16
+ const inhabitantTax = this._income * this._rules.inhabitantTax.rate;
17
+ const totalDeductions = grossTax + inhabitantTax;
18
+ const netIncome = this._income - totalDeductions;
19
+
20
+ return {
21
+ grossIncome: this._income,
22
+ nationalIncomeTax: this.round(grossTax),
23
+ inhabitantTax: this.round(inhabitantTax),
24
+ totalDeductions: this.round(totalDeductions),
25
+ netIncome: this.round(netIncome),
26
+ effectiveTaxRate: this._income > 0 ? this.round(grossTax / this._income, 4) : 0,
27
+ taxBracketBreakdown: bracketBreakdown,
28
+ };
29
+ }
30
+
31
+ private computeTaxBrackets(
32
+ income: number,
33
+ ): { grossTax: number; bracketBreakdown: BracketAllocation[] } {
34
+ let tax = 0;
35
+ const bracketBreakdown: BracketAllocation[] = [];
36
+
37
+ for (let index = 0; index < this._rules.taxBrackets.length; index++) {
38
+ const bracket = this._rules.taxBrackets[index];
39
+
40
+ if (income <= bracket.from) {
41
+ bracketBreakdown.push({
42
+ bracketIndex: index,
43
+ bracketName: `Bracket ${index + 1}`,
44
+ from: bracket.from,
45
+ to: bracket.to ?? null,
46
+ rate: bracket.rate,
47
+ amountInBracket: 0,
48
+ taxOnAmount: 0,
49
+ });
50
+ break;
51
+ }
52
+
53
+ const upper = bracket.to ?? income;
54
+ const taxableAmount = Math.min(upper, income) - bracket.from;
55
+
56
+ if (taxableAmount > 0) {
57
+ const taxOnAmount = taxableAmount * bracket.rate;
58
+ tax += taxOnAmount;
59
+ bracketBreakdown.push({
60
+ bracketIndex: index,
61
+ bracketName: `Bracket ${index + 1}`,
62
+ from: bracket.from,
63
+ to: bracket.to ?? null,
64
+ rate: bracket.rate,
65
+ amountInBracket: taxableAmount,
66
+ taxOnAmount,
67
+ });
68
+ } else {
69
+ bracketBreakdown.push({
70
+ bracketIndex: index,
71
+ bracketName: `Bracket ${index + 1}`,
72
+ from: bracket.from,
73
+ to: bracket.to ?? null,
74
+ rate: bracket.rate,
75
+ amountInBracket: 0,
76
+ taxOnAmount: 0,
77
+ });
78
+ }
79
+ }
80
+
81
+ return { grossTax: tax, bracketBreakdown };
82
+ }
83
+
84
+ private round(value: number, decimals = 2): number {
85
+ return Number(value.toFixed(decimals));
86
+ }
87
+ }
@@ -0,0 +1,16 @@
1
+ import { BracketAllocation, TaxBracket } from "../../domain/types";
2
+
3
+ export interface IncomeTaxRules {
4
+ taxBrackets: TaxBracket[];
5
+ inhabitantTax: { rate: number };
6
+ }
7
+
8
+ export interface ComputedIncomeTaxValues {
9
+ grossIncome: number;
10
+ nationalIncomeTax: number;
11
+ inhabitantTax: number;
12
+ totalDeductions: number;
13
+ netIncome: number;
14
+ effectiveTaxRate: number;
15
+ taxBracketBreakdown: BracketAllocation[];
16
+ }
@@ -0,0 +1,5 @@
1
+ import { ComputedIncomeTaxValues } from "./domain/types";
2
+
3
+ export interface SpainIncomeTaxService {
4
+ calculateNetIncome(): ComputedIncomeTaxValues;
5
+ }
@@ -0,0 +1,75 @@
1
+ import { BracketAllocation } from "../domain/types";
2
+ import { SpainIncomeTaxService } from "./SpainIncomeTaxService";
3
+ import { ComputedIncomeTaxValues, IncomeTaxRules } from "./domain/types";
4
+
5
+ export class SpainIncomeTaxServiceImpl implements SpainIncomeTaxService {
6
+ private _income: number;
7
+ private _rules: IncomeTaxRules;
8
+
9
+ constructor(income: number, rules: IncomeTaxRules) {
10
+ this._income = income;
11
+ this._rules = rules;
12
+ }
13
+
14
+ public calculateNetIncome(): ComputedIncomeTaxValues {
15
+ const { grossTax, bracketBreakdown } = this.computeTaxBrackets(this._income);
16
+ const socialContributions = this._income * this._rules.socialContributions.rate;
17
+ const totalDeductions = grossTax + socialContributions;
18
+ const netIncome = this._income - totalDeductions;
19
+
20
+ return {
21
+ grossIncome: this._income,
22
+ incomeTax: this.round(grossTax),
23
+ socialContributions: this.round(socialContributions),
24
+ totalDeductions: this.round(totalDeductions),
25
+ netIncome: this.round(netIncome),
26
+ effectiveTaxRate: this._income > 0 ? this.round(grossTax / this._income, 4) : 0,
27
+ taxBracketBreakdown: bracketBreakdown,
28
+ };
29
+ }
30
+
31
+ private computeTaxBrackets(
32
+ income: number,
33
+ ): { grossTax: number; bracketBreakdown: BracketAllocation[] } {
34
+ let tax = 0;
35
+ const bracketBreakdown: BracketAllocation[] = [];
36
+
37
+ for (let index = 0; index < this._rules.taxBrackets.length; index++) {
38
+ const bracket = this._rules.taxBrackets[index];
39
+
40
+ if (income <= bracket.from) {
41
+ bracketBreakdown.push({
42
+ bracketIndex: index,
43
+ bracketName: `Bracket ${index + 1}`,
44
+ from: bracket.from,
45
+ to: bracket.to ?? null,
46
+ rate: bracket.rate,
47
+ amountInBracket: 0,
48
+ taxOnAmount: 0,
49
+ });
50
+ break;
51
+ }
52
+
53
+ const upper = bracket.to ?? income;
54
+ const taxableAmount = Math.min(upper, income) - bracket.from;
55
+
56
+ const taxOnAmount = taxableAmount * bracket.rate;
57
+ tax += taxOnAmount;
58
+ bracketBreakdown.push({
59
+ bracketIndex: index,
60
+ bracketName: `Bracket ${index + 1}`,
61
+ from: bracket.from,
62
+ to: bracket.to ?? null,
63
+ rate: bracket.rate,
64
+ amountInBracket: taxableAmount,
65
+ taxOnAmount,
66
+ });
67
+ }
68
+
69
+ return { grossTax: tax, bracketBreakdown };
70
+ }
71
+
72
+ private round(value: number, decimals = 2): number {
73
+ return Number(value.toFixed(decimals));
74
+ }
75
+ }
@@ -0,0 +1,16 @@
1
+ import { BracketAllocation, TaxBracket } from "../../domain/types";
2
+
3
+ export interface IncomeTaxRules {
4
+ taxBrackets: TaxBracket[];
5
+ socialContributions: { rate: number };
6
+ }
7
+
8
+ export interface ComputedIncomeTaxValues {
9
+ grossIncome: number;
10
+ incomeTax: number;
11
+ socialContributions: number;
12
+ totalDeductions: number;
13
+ netIncome: number;
14
+ effectiveTaxRate: number;
15
+ taxBracketBreakdown: BracketAllocation[];
16
+ }
@@ -54,6 +54,22 @@ import {
54
54
  Result as GermanyInheritanceTaxResult,
55
55
  } from './germany/domain/types';
56
56
 
57
+ // Spain
58
+ import { SpainInheritanceTaxServiceImpl as SpainInheritanceTaxService } from './spain/SpainInheritanceTaxServiceImpl';
59
+ import {
60
+ Input as SpainInheritanceTaxInput,
61
+ Rules as SpainInheritanceTaxRules,
62
+ Result as SpainInheritanceTaxResult,
63
+ } from './spain/domain/types';
64
+
65
+ // Japan
66
+ import { JapanInheritanceTaxServiceImpl as JapanInheritanceTaxService } from './japan/JapanInheritanceTaxServiceImpl';
67
+ import {
68
+ Input as JapanInheritanceTaxInput,
69
+ Rules as JapanInheritanceTaxRules,
70
+ Result as JapanInheritanceTaxResult,
71
+ } from './japan/domain/types';
72
+
57
73
  export {
58
74
  CanadaInheritanceTaxService,
59
75
  CanadaInheritanceTaxInput,
@@ -83,4 +99,12 @@ export {
83
99
  GermanyInheritanceTaxInput,
84
100
  GermanyInheritanceTaxRules,
85
101
  GermanyInheritanceTaxResult,
102
+ SpainInheritanceTaxService,
103
+ SpainInheritanceTaxInput,
104
+ SpainInheritanceTaxRules,
105
+ SpainInheritanceTaxResult,
106
+ JapanInheritanceTaxService,
107
+ JapanInheritanceTaxInput,
108
+ JapanInheritanceTaxRules,
109
+ JapanInheritanceTaxResult,
86
110
  };
@@ -0,0 +1,5 @@
1
+ import { Result } from "./domain/types";
2
+
3
+ export interface JapanInheritanceTaxService {
4
+ calculate(): Result;
5
+ }