@novha/calc-engines 4.0.0 → 5.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.
- package/dist/capital-gains/australia/AustraliaCapitalGainsService.js +3 -0
- package/dist/capital-gains/australia/AustraliaCapitalGainsServiceImpl.js +56 -0
- package/dist/capital-gains/australia/domain/types.js +3 -0
- package/dist/capital-gains/canada/CanadaCapitalGainsService.js +3 -0
- package/dist/capital-gains/canada/CanadaCapitalGainsServiceImpl.js +55 -0
- package/dist/capital-gains/canada/domain/types.js +3 -0
- package/dist/capital-gains/domain/types.js +3 -0
- package/dist/capital-gains/france/FranceCapitalGainsService.js +3 -0
- package/dist/capital-gains/france/FranceCapitalGainsServiceImpl.js +41 -0
- package/dist/capital-gains/france/domain/types.js +3 -0
- package/dist/capital-gains/germany/GermanyCapitalGainsService.js +3 -0
- package/dist/capital-gains/germany/GermanyCapitalGainsServiceImpl.js +65 -0
- package/dist/capital-gains/germany/domain/types.js +3 -0
- package/dist/capital-gains/south-africa/SouthAfricaCapitalGainsService.js +3 -0
- package/dist/capital-gains/south-africa/SouthAfricaCapitalGainsServiceImpl.js +69 -0
- package/dist/capital-gains/south-africa/domain/types.js +3 -0
- package/dist/capital-gains/uk/UKCapitalGainsService.js +3 -0
- package/dist/capital-gains/uk/UKCapitalGainsServiceImpl.js +72 -0
- package/dist/capital-gains/uk/domain/types.js +3 -0
- package/dist/capital-gains/usa/USACapitalGainsService.js +3 -0
- package/dist/capital-gains/usa/USACapitalGainsServiceImpl.js +67 -0
- package/dist/capital-gains/usa/domain/types.js +3 -0
- package/dist/index.js +23 -2
- package/dist/shared/domain/types.js +2 -1
- package/dist/types/capital-gains/australia/AustraliaCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/australia/AustraliaCapitalGainsServiceImpl.d.ts +9 -0
- package/dist/types/capital-gains/australia/domain/types.d.ts +22 -0
- package/dist/types/capital-gains/canada/CanadaCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/canada/CanadaCapitalGainsServiceImpl.d.ts +9 -0
- package/dist/types/capital-gains/canada/domain/types.d.ts +20 -0
- package/dist/types/capital-gains/domain/types.d.ts +6 -0
- package/dist/types/capital-gains/france/FranceCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/france/FranceCapitalGainsServiceImpl.d.ts +8 -0
- package/dist/types/capital-gains/france/domain/types.d.ts +15 -0
- package/dist/types/capital-gains/germany/GermanyCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/germany/GermanyCapitalGainsServiceImpl.d.ts +8 -0
- package/dist/types/capital-gains/germany/domain/types.d.ts +17 -0
- package/dist/types/capital-gains/south-africa/SouthAfricaCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/south-africa/SouthAfricaCapitalGainsServiceImpl.d.ts +9 -0
- package/dist/types/capital-gains/south-africa/domain/types.d.ts +21 -0
- package/dist/types/capital-gains/uk/UKCapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/uk/UKCapitalGainsServiceImpl.d.ts +8 -0
- package/dist/types/capital-gains/uk/domain/types.d.ts +17 -0
- package/dist/types/capital-gains/usa/USACapitalGainsService.d.ts +4 -0
- package/dist/types/capital-gains/usa/USACapitalGainsServiceImpl.d.ts +9 -0
- package/dist/types/capital-gains/usa/domain/types.d.ts +26 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/shared/domain/types.d.ts +2 -1
- package/package.json +1 -1
- package/src/capital-gains/australia/AustraliaCapitalGainsService.ts +5 -0
- package/src/capital-gains/australia/AustraliaCapitalGainsServiceImpl.ts +73 -0
- package/src/capital-gains/australia/domain/types.ts +26 -0
- package/src/capital-gains/canada/CanadaCapitalGainsService.ts +5 -0
- package/src/capital-gains/canada/CanadaCapitalGainsServiceImpl.ts +71 -0
- package/src/capital-gains/canada/domain/types.ts +24 -0
- package/src/capital-gains/domain/types.ts +6 -0
- package/src/capital-gains/france/FranceCapitalGainsService.ts +5 -0
- package/src/capital-gains/france/FranceCapitalGainsServiceImpl.ts +48 -0
- package/src/capital-gains/france/domain/types.ts +18 -0
- package/src/capital-gains/germany/GermanyCapitalGainsService.ts +5 -0
- package/src/capital-gains/germany/GermanyCapitalGainsServiceImpl.ts +74 -0
- package/src/capital-gains/germany/domain/types.ts +20 -0
- package/src/capital-gains/south-africa/SouthAfricaCapitalGainsService.ts +5 -0
- package/src/capital-gains/south-africa/SouthAfricaCapitalGainsServiceImpl.ts +87 -0
- package/src/capital-gains/south-africa/domain/types.ts +25 -0
- package/src/capital-gains/uk/UKCapitalGainsService.ts +5 -0
- package/src/capital-gains/uk/UKCapitalGainsServiceImpl.ts +84 -0
- package/src/capital-gains/uk/domain/types.ts +20 -0
- package/src/capital-gains/usa/USACapitalGainsService.ts +5 -0
- package/src/capital-gains/usa/USACapitalGainsServiceImpl.ts +86 -0
- package/src/capital-gains/usa/domain/types.ts +27 -0
- package/src/index.ts +56 -0
- package/src/shared/domain/types.ts +1 -0
- package/test/australia-capital-gains.test.ts +80 -0
- package/test/canada-capital-gains.test.ts +71 -0
- package/test/france-capital-gains.test.ts +66 -0
- package/test/germany-capital-gains.test.ts +85 -0
- package/test/south-africa-capital-gains.test.ts +84 -0
- package/test/uk-capital-gains.test.ts +79 -0
- package/test/usa-capital-gains.test.ts +88 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXVzdHJhbGlhQ2FwaXRhbEdhaW5zU2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jYXBpdGFsLWdhaW5zL2F1c3RyYWxpYS9BdXN0cmFsaWFDYXBpdGFsR2FpbnNTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXN1bHQgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBBdXN0cmFsaWFDYXBpdGFsR2FpbnNTZXJ2aWNlIHtcbiAgICBjYWxjdWxhdGUoKTogUmVzdWx0O1xufVxuIl19
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AustraliaCapitalGainsServiceImpl = void 0;
|
|
4
|
+
class AustraliaCapitalGainsServiceImpl {
|
|
5
|
+
constructor(input, rules) {
|
|
6
|
+
this._input = input;
|
|
7
|
+
this._rules = rules;
|
|
8
|
+
}
|
|
9
|
+
calculate() {
|
|
10
|
+
const gain = this._input.capitalGain;
|
|
11
|
+
if (gain <= 0) {
|
|
12
|
+
return { taxableGain: 0, capitalGainsTax: 0, effectiveRate: 0, breakdowns: [] };
|
|
13
|
+
}
|
|
14
|
+
const eligible = this._input.holdingPeriodMonths >= this._rules.cgtDiscountMinMonths;
|
|
15
|
+
const taxableGain = eligible ? gain * (1 - this._rules.cgtDiscount) : gain;
|
|
16
|
+
const otherIncome = this._input.totalTaxableIncome - gain;
|
|
17
|
+
const { tax, breakdowns } = this.applyBrackets(taxableGain, otherIncome, this._rules.taxBrackets);
|
|
18
|
+
return {
|
|
19
|
+
taxableGain,
|
|
20
|
+
capitalGainsTax: tax,
|
|
21
|
+
effectiveRate: gain > 0 ? (tax / gain) * 100 : 0,
|
|
22
|
+
breakdowns,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
applyBrackets(taxableGain, otherIncome, brackets) {
|
|
26
|
+
let tax = 0;
|
|
27
|
+
const breakdowns = [];
|
|
28
|
+
let remaining = taxableGain;
|
|
29
|
+
let incomeUsed = otherIncome;
|
|
30
|
+
for (const bracket of brackets) {
|
|
31
|
+
if (remaining <= 0)
|
|
32
|
+
break;
|
|
33
|
+
const upper = bracket.to ?? Infinity;
|
|
34
|
+
if (incomeUsed >= upper)
|
|
35
|
+
continue;
|
|
36
|
+
const bracketStart = Math.max(bracket.from, incomeUsed);
|
|
37
|
+
const bracketSpace = upper - bracketStart;
|
|
38
|
+
const taxable = Math.min(bracketSpace, remaining);
|
|
39
|
+
if (taxable > 0) {
|
|
40
|
+
const bracketTax = taxable * bracket.rate;
|
|
41
|
+
tax += bracketTax;
|
|
42
|
+
remaining -= taxable;
|
|
43
|
+
incomeUsed += taxable;
|
|
44
|
+
breakdowns.push({
|
|
45
|
+
from: `${bracket.from}`,
|
|
46
|
+
to: `${bracket.to ?? 'Above'}`,
|
|
47
|
+
rate: bracket.rate,
|
|
48
|
+
amount: bracketTax,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { tax, breakdowns };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.AustraliaCapitalGainsServiceImpl = AustraliaCapitalGainsServiceImpl;
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXVzdHJhbGlhQ2FwaXRhbEdhaW5zU2VydmljZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9hdXN0cmFsaWEvQXVzdHJhbGlhQ2FwaXRhbEdhaW5zU2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsTUFBYSxnQ0FBZ0M7SUFJekMsWUFBWSxLQUFZLEVBQUUsS0FBWTtRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsU0FBUztRQUNMLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBRXJDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ1osT0FBTyxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsZUFBZSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNwRixDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDO1FBQ3JGLE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUUzRSxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztRQUMxRCxNQUFNLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRWxHLE9BQU87WUFDSCxXQUFXO1lBQ1gsZUFBZSxFQUFFLEdBQUc7WUFDcEIsYUFBYSxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoRCxVQUFVO1NBQ2IsQ0FBQztJQUNOLENBQUM7SUFFTyxhQUFhLENBQ2pCLFdBQW1CLEVBQ25CLFdBQW1CLEVBQ25CLFFBQXNCO1FBRXRCLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLE1BQU0sVUFBVSxHQUFnQixFQUFFLENBQUM7UUFDbkMsSUFBSSxTQUFTLEdBQUcsV0FBVyxDQUFDO1FBQzVCLElBQUksVUFBVSxHQUFHLFdBQVcsQ0FBQztRQUU3QixLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQzdCLElBQUksU0FBUyxJQUFJLENBQUM7Z0JBQUUsTUFBTTtZQUUxQixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsRUFBRSxJQUFJLFFBQVEsQ0FBQztZQUVyQyxJQUFJLFVBQVUsSUFBSSxLQUFLO2dCQUFFLFNBQVM7WUFFbEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3hELE1BQU0sWUFBWSxHQUFHLEtBQUssR0FBRyxZQUFZLENBQUM7WUFDMUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFbEQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2QsTUFBTSxVQUFVLEdBQUcsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQzFDLEdBQUcsSUFBSSxVQUFVLENBQUM7Z0JBQ2xCLFNBQVMsSUFBSSxPQUFPLENBQUM7Z0JBQ3JCLFVBQVUsSUFBSSxPQUFPLENBQUM7Z0JBRXRCLFVBQVUsQ0FBQyxJQUFJLENBQUM7b0JBQ1osSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRTtvQkFDdkIsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsSUFBSSxPQUFPLEVBQUU7b0JBQzlCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtvQkFDbEIsTUFBTSxFQUFFLFVBQVU7aUJBQ3JCLENBQUMsQ0FBQztZQUNQLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUMvQixDQUFDO0NBQ0o7QUFwRUQsNEVBb0VDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQnJlYWtkb3duIH0gZnJvbSBcIi4uL2RvbWFpbi90eXBlc1wiO1xuaW1wb3J0IHsgQXVzdHJhbGlhQ2FwaXRhbEdhaW5zU2VydmljZSB9IGZyb20gXCIuL0F1c3RyYWxpYUNhcGl0YWxHYWluc1NlcnZpY2VcIjtcbmltcG9ydCB7IElucHV0LCBSZXN1bHQsIFJ1bGVzLCBUYXhCcmFja2V0IH0gZnJvbSBcIi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBBdXN0cmFsaWFDYXBpdGFsR2FpbnNTZXJ2aWNlSW1wbCBpbXBsZW1lbnRzIEF1c3RyYWxpYUNhcGl0YWxHYWluc1NlcnZpY2Uge1xuICAgIHByaXZhdGUgX2lucHV0OiBJbnB1dDtcbiAgICBwcml2YXRlIF9ydWxlczogUnVsZXM7XG5cbiAgICBjb25zdHJ1Y3RvcihpbnB1dDogSW5wdXQsIHJ1bGVzOiBSdWxlcykge1xuICAgICAgICB0aGlzLl9pbnB1dCA9IGlucHV0O1xuICAgICAgICB0aGlzLl9ydWxlcyA9IHJ1bGVzO1xuICAgIH1cblxuICAgIGNhbGN1bGF0ZSgpOiBSZXN1bHQge1xuICAgICAgICBjb25zdCBnYWluID0gdGhpcy5faW5wdXQuY2FwaXRhbEdhaW47XG5cbiAgICAgICAgaWYgKGdhaW4gPD0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgdGF4YWJsZUdhaW46IDAsIGNhcGl0YWxHYWluc1RheDogMCwgZWZmZWN0aXZlUmF0ZTogMCwgYnJlYWtkb3duczogW10gfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVsaWdpYmxlID0gdGhpcy5faW5wdXQuaG9sZGluZ1BlcmlvZE1vbnRocyA+PSB0aGlzLl9ydWxlcy5jZ3REaXNjb3VudE1pbk1vbnRocztcbiAgICAgICAgY29uc3QgdGF4YWJsZUdhaW4gPSBlbGlnaWJsZSA/IGdhaW4gKiAoMSAtIHRoaXMuX3J1bGVzLmNndERpc2NvdW50KSA6IGdhaW47XG5cbiAgICAgICAgY29uc3Qgb3RoZXJJbmNvbWUgPSB0aGlzLl9pbnB1dC50b3RhbFRheGFibGVJbmNvbWUgLSBnYWluO1xuICAgICAgICBjb25zdCB7IHRheCwgYnJlYWtkb3ducyB9ID0gdGhpcy5hcHBseUJyYWNrZXRzKHRheGFibGVHYWluLCBvdGhlckluY29tZSwgdGhpcy5fcnVsZXMudGF4QnJhY2tldHMpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0YXhhYmxlR2FpbixcbiAgICAgICAgICAgIGNhcGl0YWxHYWluc1RheDogdGF4LFxuICAgICAgICAgICAgZWZmZWN0aXZlUmF0ZTogZ2FpbiA+IDAgPyAodGF4IC8gZ2FpbikgKiAxMDAgOiAwLFxuICAgICAgICAgICAgYnJlYWtkb3ducyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFwcGx5QnJhY2tldHMoXG4gICAgICAgIHRheGFibGVHYWluOiBudW1iZXIsXG4gICAgICAgIG90aGVySW5jb21lOiBudW1iZXIsXG4gICAgICAgIGJyYWNrZXRzOiBUYXhCcmFja2V0W10sXG4gICAgKTogeyB0YXg6IG51bWJlcjsgYnJlYWtkb3duczogQnJlYWtkb3duW10gfSB7XG4gICAgICAgIGxldCB0YXggPSAwO1xuICAgICAgICBjb25zdCBicmVha2Rvd25zOiBCcmVha2Rvd25bXSA9IFtdO1xuICAgICAgICBsZXQgcmVtYWluaW5nID0gdGF4YWJsZUdhaW47XG4gICAgICAgIGxldCBpbmNvbWVVc2VkID0gb3RoZXJJbmNvbWU7XG5cbiAgICAgICAgZm9yIChjb25zdCBicmFja2V0IG9mIGJyYWNrZXRzKSB7XG4gICAgICAgICAgICBpZiAocmVtYWluaW5nIDw9IDApIGJyZWFrO1xuXG4gICAgICAgICAgICBjb25zdCB1cHBlciA9IGJyYWNrZXQudG8gPz8gSW5maW5pdHk7XG5cbiAgICAgICAgICAgIGlmIChpbmNvbWVVc2VkID49IHVwcGVyKSBjb250aW51ZTtcblxuICAgICAgICAgICAgY29uc3QgYnJhY2tldFN0YXJ0ID0gTWF0aC5tYXgoYnJhY2tldC5mcm9tLCBpbmNvbWVVc2VkKTtcbiAgICAgICAgICAgIGNvbnN0IGJyYWNrZXRTcGFjZSA9IHVwcGVyIC0gYnJhY2tldFN0YXJ0O1xuICAgICAgICAgICAgY29uc3QgdGF4YWJsZSA9IE1hdGgubWluKGJyYWNrZXRTcGFjZSwgcmVtYWluaW5nKTtcblxuICAgICAgICAgICAgaWYgKHRheGFibGUgPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnJhY2tldFRheCA9IHRheGFibGUgKiBicmFja2V0LnJhdGU7XG4gICAgICAgICAgICAgICAgdGF4ICs9IGJyYWNrZXRUYXg7XG4gICAgICAgICAgICAgICAgcmVtYWluaW5nIC09IHRheGFibGU7XG4gICAgICAgICAgICAgICAgaW5jb21lVXNlZCArPSB0YXhhYmxlO1xuXG4gICAgICAgICAgICAgICAgYnJlYWtkb3ducy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogYCR7YnJhY2tldC5mcm9tfWAsXG4gICAgICAgICAgICAgICAgICAgIHRvOiBgJHticmFja2V0LnRvID8/ICdBYm92ZSd9YCxcbiAgICAgICAgICAgICAgICAgICAgcmF0ZTogYnJhY2tldC5yYXRlLFxuICAgICAgICAgICAgICAgICAgICBhbW91bnQ6IGJyYWNrZXRUYXgsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyB0YXgsIGJyZWFrZG93bnMgfTtcbiAgICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9hdXN0cmFsaWEvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmVha2Rvd24gfSBmcm9tIFwiLi4vLi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGF4QnJhY2tldCB7XG4gICAgZnJvbTogbnVtYmVyO1xuICAgIHRvOiBudW1iZXIgfCBudWxsO1xuICAgIHJhdGU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdWxlcyB7XG4gICAgY2d0RGlzY291bnQ6IG51bWJlcjtcbiAgICBjZ3REaXNjb3VudE1pbk1vbnRoczogbnVtYmVyO1xuICAgIHRheEJyYWNrZXRzOiBUYXhCcmFja2V0W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXQge1xuICAgIGNhcGl0YWxHYWluOiBudW1iZXI7XG4gICAgdG90YWxUYXhhYmxlSW5jb21lOiBudW1iZXI7XG4gICAgaG9sZGluZ1BlcmlvZE1vbnRoczogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlc3VsdCB7XG4gICAgdGF4YWJsZUdhaW46IG51bWJlcjtcbiAgICBjYXBpdGFsR2FpbnNUYXg6IG51bWJlcjtcbiAgICBlZmZlY3RpdmVSYXRlOiBudW1iZXI7XG4gICAgYnJlYWtkb3duczogQnJlYWtkb3duW107XG59XG4iXX0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FuYWRhQ2FwaXRhbEdhaW5zU2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jYXBpdGFsLWdhaW5zL2NhbmFkYS9DYW5hZGFDYXBpdGFsR2FpbnNTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXN1bHQgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBDYW5hZGFDYXBpdGFsR2FpbnNTZXJ2aWNlIHtcbiAgICBjYWxjdWxhdGUoKTogUmVzdWx0O1xufVxuIl19
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CanadaCapitalGainsServiceImpl = void 0;
|
|
4
|
+
class CanadaCapitalGainsServiceImpl {
|
|
5
|
+
constructor(input, rules) {
|
|
6
|
+
this._input = input;
|
|
7
|
+
this._rules = rules;
|
|
8
|
+
}
|
|
9
|
+
calculate() {
|
|
10
|
+
const gain = this._input.capitalGain;
|
|
11
|
+
if (gain <= 0) {
|
|
12
|
+
return { taxableGain: 0, capitalGainsTax: 0, effectiveRate: 0, breakdowns: [] };
|
|
13
|
+
}
|
|
14
|
+
const taxableGain = gain * this._rules.inclusionRate;
|
|
15
|
+
const otherIncome = this._input.totalTaxableIncome - gain;
|
|
16
|
+
const { tax, breakdowns } = this.applyBrackets(taxableGain, otherIncome, this._rules.taxBrackets);
|
|
17
|
+
return {
|
|
18
|
+
taxableGain,
|
|
19
|
+
capitalGainsTax: tax,
|
|
20
|
+
effectiveRate: gain > 0 ? (tax / gain) * 100 : 0,
|
|
21
|
+
breakdowns,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
applyBrackets(taxableGain, otherIncome, brackets) {
|
|
25
|
+
let tax = 0;
|
|
26
|
+
const breakdowns = [];
|
|
27
|
+
let remaining = taxableGain;
|
|
28
|
+
let incomeUsed = otherIncome;
|
|
29
|
+
for (const bracket of brackets) {
|
|
30
|
+
if (remaining <= 0)
|
|
31
|
+
break;
|
|
32
|
+
const upper = bracket.to ?? Infinity;
|
|
33
|
+
if (incomeUsed >= upper)
|
|
34
|
+
continue;
|
|
35
|
+
const bracketStart = Math.max(bracket.from, incomeUsed);
|
|
36
|
+
const bracketSpace = upper - bracketStart;
|
|
37
|
+
const taxable = Math.min(bracketSpace, remaining);
|
|
38
|
+
if (taxable > 0) {
|
|
39
|
+
const bracketTax = taxable * bracket.rate;
|
|
40
|
+
tax += bracketTax;
|
|
41
|
+
remaining -= taxable;
|
|
42
|
+
incomeUsed += taxable;
|
|
43
|
+
breakdowns.push({
|
|
44
|
+
from: `${bracket.from}`,
|
|
45
|
+
to: `${bracket.to ?? 'Above'}`,
|
|
46
|
+
rate: bracket.rate,
|
|
47
|
+
amount: bracketTax,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { tax, breakdowns };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.CanadaCapitalGainsServiceImpl = CanadaCapitalGainsServiceImpl;
|
|
55
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FuYWRhQ2FwaXRhbEdhaW5zU2VydmljZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9jYW5hZGEvQ2FuYWRhQ2FwaXRhbEdhaW5zU2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsTUFBYSw2QkFBNkI7SUFJdEMsWUFBWSxLQUFZLEVBQUUsS0FBWTtRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsU0FBUztRQUNMLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBRXJDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ1osT0FBTyxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsZUFBZSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNwRixDQUFDO1FBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDO1FBQ3JELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO1FBQzFELE1BQU0sRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFbEcsT0FBTztZQUNILFdBQVc7WUFDWCxlQUFlLEVBQUUsR0FBRztZQUNwQixhQUFhLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hELFVBQVU7U0FDYixDQUFDO0lBQ04sQ0FBQztJQUVPLGFBQWEsQ0FDakIsV0FBbUIsRUFDbkIsV0FBbUIsRUFDbkIsUUFBc0I7UUFFdEIsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1osTUFBTSxVQUFVLEdBQWdCLEVBQUUsQ0FBQztRQUNuQyxJQUFJLFNBQVMsR0FBRyxXQUFXLENBQUM7UUFDNUIsSUFBSSxVQUFVLEdBQUcsV0FBVyxDQUFDO1FBRTdCLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7WUFDN0IsSUFBSSxTQUFTLElBQUksQ0FBQztnQkFBRSxNQUFNO1lBRTFCLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxFQUFFLElBQUksUUFBUSxDQUFDO1lBRXJDLElBQUksVUFBVSxJQUFJLEtBQUs7Z0JBQUUsU0FBUztZQUVsQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDeEQsTUFBTSxZQUFZLEdBQUcsS0FBSyxHQUFHLFlBQVksQ0FBQztZQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVsRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDZCxNQUFNLFVBQVUsR0FBRyxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztnQkFDMUMsR0FBRyxJQUFJLFVBQVUsQ0FBQztnQkFDbEIsU0FBUyxJQUFJLE9BQU8sQ0FBQztnQkFDckIsVUFBVSxJQUFJLE9BQU8sQ0FBQztnQkFFdEIsVUFBVSxDQUFDLElBQUksQ0FBQztvQkFDWixJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxFQUFFO29CQUN2QixFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUMsRUFBRSxJQUFJLE9BQU8sRUFBRTtvQkFDOUIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO29CQUNsQixNQUFNLEVBQUUsVUFBVTtpQkFDckIsQ0FBQyxDQUFDO1lBQ1AsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxDQUFDO0lBQy9CLENBQUM7Q0FDSjtBQWxFRCxzRUFrRUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmVha2Rvd24gfSBmcm9tIFwiLi4vZG9tYWluL3R5cGVzXCI7XG5pbXBvcnQgeyBDYW5hZGFDYXBpdGFsR2FpbnNTZXJ2aWNlIH0gZnJvbSBcIi4vQ2FuYWRhQ2FwaXRhbEdhaW5zU2VydmljZVwiO1xuaW1wb3J0IHsgSW5wdXQsIFJlc3VsdCwgUnVsZXMsIFRheEJyYWNrZXQgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIENhbmFkYUNhcGl0YWxHYWluc1NlcnZpY2VJbXBsIGltcGxlbWVudHMgQ2FuYWRhQ2FwaXRhbEdhaW5zU2VydmljZSB7XG4gICAgcHJpdmF0ZSBfaW5wdXQ6IElucHV0O1xuICAgIHByaXZhdGUgX3J1bGVzOiBSdWxlcztcblxuICAgIGNvbnN0cnVjdG9yKGlucHV0OiBJbnB1dCwgcnVsZXM6IFJ1bGVzKSB7XG4gICAgICAgIHRoaXMuX2lucHV0ID0gaW5wdXQ7XG4gICAgICAgIHRoaXMuX3J1bGVzID0gcnVsZXM7XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlKCk6IFJlc3VsdCB7XG4gICAgICAgIGNvbnN0IGdhaW4gPSB0aGlzLl9pbnB1dC5jYXBpdGFsR2FpbjtcblxuICAgICAgICBpZiAoZ2FpbiA8PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4geyB0YXhhYmxlR2FpbjogMCwgY2FwaXRhbEdhaW5zVGF4OiAwLCBlZmZlY3RpdmVSYXRlOiAwLCBicmVha2Rvd25zOiBbXSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGF4YWJsZUdhaW4gPSBnYWluICogdGhpcy5fcnVsZXMuaW5jbHVzaW9uUmF0ZTtcbiAgICAgICAgY29uc3Qgb3RoZXJJbmNvbWUgPSB0aGlzLl9pbnB1dC50b3RhbFRheGFibGVJbmNvbWUgLSBnYWluO1xuICAgICAgICBjb25zdCB7IHRheCwgYnJlYWtkb3ducyB9ID0gdGhpcy5hcHBseUJyYWNrZXRzKHRheGFibGVHYWluLCBvdGhlckluY29tZSwgdGhpcy5fcnVsZXMudGF4QnJhY2tldHMpO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0YXhhYmxlR2FpbixcbiAgICAgICAgICAgIGNhcGl0YWxHYWluc1RheDogdGF4LFxuICAgICAgICAgICAgZWZmZWN0aXZlUmF0ZTogZ2FpbiA+IDAgPyAodGF4IC8gZ2FpbikgKiAxMDAgOiAwLFxuICAgICAgICAgICAgYnJlYWtkb3ducyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFwcGx5QnJhY2tldHMoXG4gICAgICAgIHRheGFibGVHYWluOiBudW1iZXIsXG4gICAgICAgIG90aGVySW5jb21lOiBudW1iZXIsXG4gICAgICAgIGJyYWNrZXRzOiBUYXhCcmFja2V0W10sXG4gICAgKTogeyB0YXg6IG51bWJlcjsgYnJlYWtkb3duczogQnJlYWtkb3duW10gfSB7XG4gICAgICAgIGxldCB0YXggPSAwO1xuICAgICAgICBjb25zdCBicmVha2Rvd25zOiBCcmVha2Rvd25bXSA9IFtdO1xuICAgICAgICBsZXQgcmVtYWluaW5nID0gdGF4YWJsZUdhaW47XG4gICAgICAgIGxldCBpbmNvbWVVc2VkID0gb3RoZXJJbmNvbWU7XG5cbiAgICAgICAgZm9yIChjb25zdCBicmFja2V0IG9mIGJyYWNrZXRzKSB7XG4gICAgICAgICAgICBpZiAocmVtYWluaW5nIDw9IDApIGJyZWFrO1xuXG4gICAgICAgICAgICBjb25zdCB1cHBlciA9IGJyYWNrZXQudG8gPz8gSW5maW5pdHk7XG5cbiAgICAgICAgICAgIGlmIChpbmNvbWVVc2VkID49IHVwcGVyKSBjb250aW51ZTtcblxuICAgICAgICAgICAgY29uc3QgYnJhY2tldFN0YXJ0ID0gTWF0aC5tYXgoYnJhY2tldC5mcm9tLCBpbmNvbWVVc2VkKTtcbiAgICAgICAgICAgIGNvbnN0IGJyYWNrZXRTcGFjZSA9IHVwcGVyIC0gYnJhY2tldFN0YXJ0O1xuICAgICAgICAgICAgY29uc3QgdGF4YWJsZSA9IE1hdGgubWluKGJyYWNrZXRTcGFjZSwgcmVtYWluaW5nKTtcblxuICAgICAgICAgICAgaWYgKHRheGFibGUgPiAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnJhY2tldFRheCA9IHRheGFibGUgKiBicmFja2V0LnJhdGU7XG4gICAgICAgICAgICAgICAgdGF4ICs9IGJyYWNrZXRUYXg7XG4gICAgICAgICAgICAgICAgcmVtYWluaW5nIC09IHRheGFibGU7XG4gICAgICAgICAgICAgICAgaW5jb21lVXNlZCArPSB0YXhhYmxlO1xuXG4gICAgICAgICAgICAgICAgYnJlYWtkb3ducy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogYCR7YnJhY2tldC5mcm9tfWAsXG4gICAgICAgICAgICAgICAgICAgIHRvOiBgJHticmFja2V0LnRvID8/ICdBYm92ZSd9YCxcbiAgICAgICAgICAgICAgICAgICAgcmF0ZTogYnJhY2tldC5yYXRlLFxuICAgICAgICAgICAgICAgICAgICBhbW91bnQ6IGJyYWNrZXRUYXgsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyB0YXgsIGJyZWFrZG93bnMgfTtcbiAgICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9jYW5hZGEvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmVha2Rvd24gfSBmcm9tIFwiLi4vLi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZXMge1xuICAgIGluY2x1c2lvblJhdGU6IG51bWJlcjtcbiAgICB0YXhCcmFja2V0czogVGF4QnJhY2tldFtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRheEJyYWNrZXQge1xuICAgIGZyb206IG51bWJlcjtcbiAgICB0bzogbnVtYmVyIHwgbnVsbDtcbiAgICByYXRlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXQge1xuICAgIGNhcGl0YWxHYWluOiBudW1iZXI7XG4gICAgdG90YWxUYXhhYmxlSW5jb21lOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdWx0IHtcbiAgICB0YXhhYmxlR2FpbjogbnVtYmVyO1xuICAgIGNhcGl0YWxHYWluc1RheDogbnVtYmVyO1xuICAgIGVmZmVjdGl2ZVJhdGU6IG51bWJlcjtcbiAgICBicmVha2Rvd25zOiBCcmVha2Rvd25bXTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9kb21haW4vdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgQnJlYWtkb3duIHtcbiAgICBmcm9tOiBzdHJpbmc7XG4gICAgdG86IHN0cmluZztcbiAgICByYXRlOiBudW1iZXI7XG4gICAgYW1vdW50OiBudW1iZXI7XG59XG4iXX0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRnJhbmNlQ2FwaXRhbEdhaW5zU2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jYXBpdGFsLWdhaW5zL2ZyYW5jZS9GcmFuY2VDYXBpdGFsR2FpbnNTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXN1bHQgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBGcmFuY2VDYXBpdGFsR2FpbnNTZXJ2aWNlIHtcbiAgICBjYWxjdWxhdGUoKTogUmVzdWx0O1xufVxuIl19
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FranceCapitalGainsServiceImpl = void 0;
|
|
4
|
+
class FranceCapitalGainsServiceImpl {
|
|
5
|
+
constructor(input, rules) {
|
|
6
|
+
this._input = input;
|
|
7
|
+
this._rules = rules;
|
|
8
|
+
}
|
|
9
|
+
calculate() {
|
|
10
|
+
const gain = this._input.capitalGain;
|
|
11
|
+
if (gain <= 0) {
|
|
12
|
+
return { incomeTax: 0, socialContributions: 0, totalTax: 0, effectiveRate: 0, breakdowns: [] };
|
|
13
|
+
}
|
|
14
|
+
const incomeTax = gain * this._rules.flatTaxRate;
|
|
15
|
+
const socialContributions = gain * this._rules.socialContributionsRate;
|
|
16
|
+
const totalTax = incomeTax + socialContributions;
|
|
17
|
+
const breakdowns = [
|
|
18
|
+
{
|
|
19
|
+
from: '0',
|
|
20
|
+
to: 'All',
|
|
21
|
+
rate: this._rules.flatTaxRate,
|
|
22
|
+
amount: incomeTax,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
from: '0',
|
|
26
|
+
to: 'Social',
|
|
27
|
+
rate: this._rules.socialContributionsRate,
|
|
28
|
+
amount: socialContributions,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
return {
|
|
32
|
+
incomeTax,
|
|
33
|
+
socialContributions,
|
|
34
|
+
totalTax,
|
|
35
|
+
effectiveRate: (totalTax / gain) * 100,
|
|
36
|
+
breakdowns,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.FranceCapitalGainsServiceImpl = FranceCapitalGainsServiceImpl;
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRnJhbmNlQ2FwaXRhbEdhaW5zU2VydmljZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9mcmFuY2UvRnJhbmNlQ2FwaXRhbEdhaW5zU2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsTUFBYSw2QkFBNkI7SUFJdEMsWUFBWSxLQUFZLEVBQUUsS0FBWTtRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsU0FBUztRQUNMLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBRXJDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ1osT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDbkcsQ0FBQztRQUVELE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztRQUNqRCxNQUFNLG1CQUFtQixHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUF1QixDQUFDO1FBQ3ZFLE1BQU0sUUFBUSxHQUFHLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQztRQUVqRCxNQUFNLFVBQVUsR0FBZ0I7WUFDNUI7Z0JBQ0ksSUFBSSxFQUFFLEdBQUc7Z0JBQ1QsRUFBRSxFQUFFLEtBQUs7Z0JBQ1QsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVztnQkFDN0IsTUFBTSxFQUFFLFNBQVM7YUFDcEI7WUFDRDtnQkFDSSxJQUFJLEVBQUUsR0FBRztnQkFDVCxFQUFFLEVBQUUsUUFBUTtnQkFDWixJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUI7Z0JBQ3pDLE1BQU0sRUFBRSxtQkFBbUI7YUFDOUI7U0FDSixDQUFDO1FBRUYsT0FBTztZQUNILFNBQVM7WUFDVCxtQkFBbUI7WUFDbkIsUUFBUTtZQUNSLGFBQWEsRUFBRSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHO1lBQ3RDLFVBQVU7U0FDYixDQUFDO0lBQ04sQ0FBQztDQUNKO0FBM0NELHNFQTJDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJyZWFrZG93biB9IGZyb20gXCIuLi9kb21haW4vdHlwZXNcIjtcbmltcG9ydCB7IEZyYW5jZUNhcGl0YWxHYWluc1NlcnZpY2UgfSBmcm9tIFwiLi9GcmFuY2VDYXBpdGFsR2FpbnNTZXJ2aWNlXCI7XG5pbXBvcnQgeyBJbnB1dCwgUmVzdWx0LCBSdWxlcyB9IGZyb20gXCIuL2RvbWFpbi90eXBlc1wiO1xuXG5leHBvcnQgY2xhc3MgRnJhbmNlQ2FwaXRhbEdhaW5zU2VydmljZUltcGwgaW1wbGVtZW50cyBGcmFuY2VDYXBpdGFsR2FpbnNTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF9pbnB1dDogSW5wdXQ7XG4gICAgcHJpdmF0ZSBfcnVsZXM6IFJ1bGVzO1xuXG4gICAgY29uc3RydWN0b3IoaW5wdXQ6IElucHV0LCBydWxlczogUnVsZXMpIHtcbiAgICAgICAgdGhpcy5faW5wdXQgPSBpbnB1dDtcbiAgICAgICAgdGhpcy5fcnVsZXMgPSBydWxlcztcbiAgICB9XG5cbiAgICBjYWxjdWxhdGUoKTogUmVzdWx0IHtcbiAgICAgICAgY29uc3QgZ2FpbiA9IHRoaXMuX2lucHV0LmNhcGl0YWxHYWluO1xuXG4gICAgICAgIGlmIChnYWluIDw9IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IGluY29tZVRheDogMCwgc29jaWFsQ29udHJpYnV0aW9uczogMCwgdG90YWxUYXg6IDAsIGVmZmVjdGl2ZVJhdGU6IDAsIGJyZWFrZG93bnM6IFtdIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpbmNvbWVUYXggPSBnYWluICogdGhpcy5fcnVsZXMuZmxhdFRheFJhdGU7XG4gICAgICAgIGNvbnN0IHNvY2lhbENvbnRyaWJ1dGlvbnMgPSBnYWluICogdGhpcy5fcnVsZXMuc29jaWFsQ29udHJpYnV0aW9uc1JhdGU7XG4gICAgICAgIGNvbnN0IHRvdGFsVGF4ID0gaW5jb21lVGF4ICsgc29jaWFsQ29udHJpYnV0aW9ucztcblxuICAgICAgICBjb25zdCBicmVha2Rvd25zOiBCcmVha2Rvd25bXSA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiAnMCcsXG4gICAgICAgICAgICAgICAgdG86ICdBbGwnLFxuICAgICAgICAgICAgICAgIHJhdGU6IHRoaXMuX3J1bGVzLmZsYXRUYXhSYXRlLFxuICAgICAgICAgICAgICAgIGFtb3VudDogaW5jb21lVGF4LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiAnMCcsXG4gICAgICAgICAgICAgICAgdG86ICdTb2NpYWwnLFxuICAgICAgICAgICAgICAgIHJhdGU6IHRoaXMuX3J1bGVzLnNvY2lhbENvbnRyaWJ1dGlvbnNSYXRlLFxuICAgICAgICAgICAgICAgIGFtb3VudDogc29jaWFsQ29udHJpYnV0aW9ucyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGluY29tZVRheCxcbiAgICAgICAgICAgIHNvY2lhbENvbnRyaWJ1dGlvbnMsXG4gICAgICAgICAgICB0b3RhbFRheCxcbiAgICAgICAgICAgIGVmZmVjdGl2ZVJhdGU6ICh0b3RhbFRheCAvIGdhaW4pICogMTAwLFxuICAgICAgICAgICAgYnJlYWtkb3ducyxcbiAgICAgICAgfTtcbiAgICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9mcmFuY2UvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmVha2Rvd24gfSBmcm9tIFwiLi4vLi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZXMge1xuICAgIGZsYXRUYXhSYXRlOiBudW1iZXI7XG4gICAgc29jaWFsQ29udHJpYnV0aW9uc1JhdGU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJbnB1dCB7XG4gICAgY2FwaXRhbEdhaW46IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXN1bHQge1xuICAgIGluY29tZVRheDogbnVtYmVyO1xuICAgIHNvY2lhbENvbnRyaWJ1dGlvbnM6IG51bWJlcjtcbiAgICB0b3RhbFRheDogbnVtYmVyO1xuICAgIGVmZmVjdGl2ZVJhdGU6IG51bWJlcjtcbiAgICBicmVha2Rvd25zOiBCcmVha2Rvd25bXTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiR2VybWFueUNhcGl0YWxHYWluc1NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9nZXJtYW55L0dlcm1hbnlDYXBpdGFsR2FpbnNTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXN1bHQgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBHZXJtYW55Q2FwaXRhbEdhaW5zU2VydmljZSB7XG4gICAgY2FsY3VsYXRlKCk6IFJlc3VsdDtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GermanyCapitalGainsServiceImpl = void 0;
|
|
4
|
+
class GermanyCapitalGainsServiceImpl {
|
|
5
|
+
constructor(input, rules) {
|
|
6
|
+
this._input = input;
|
|
7
|
+
this._rules = rules;
|
|
8
|
+
}
|
|
9
|
+
calculate() {
|
|
10
|
+
const gain = this._input.capitalGain;
|
|
11
|
+
if (gain <= 0) {
|
|
12
|
+
return {
|
|
13
|
+
taxableGain: 0,
|
|
14
|
+
capitalGainsTax: 0,
|
|
15
|
+
solidaritySurcharge: 0,
|
|
16
|
+
totalTax: 0,
|
|
17
|
+
effectiveRate: 0,
|
|
18
|
+
breakdowns: [],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const taxableGain = Math.max(0, gain - this._rules.annualExemption);
|
|
22
|
+
if (taxableGain <= 0) {
|
|
23
|
+
return {
|
|
24
|
+
taxableGain: 0,
|
|
25
|
+
capitalGainsTax: 0,
|
|
26
|
+
solidaritySurcharge: 0,
|
|
27
|
+
totalTax: 0,
|
|
28
|
+
effectiveRate: 0,
|
|
29
|
+
breakdowns: [{
|
|
30
|
+
from: '0',
|
|
31
|
+
to: `${this._rules.annualExemption}`,
|
|
32
|
+
rate: 0,
|
|
33
|
+
amount: 0,
|
|
34
|
+
}],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const capitalGainsTax = taxableGain * this._rules.flatTaxRate;
|
|
38
|
+
const solidaritySurcharge = capitalGainsTax * this._rules.solidaritySurchargeRate;
|
|
39
|
+
const totalTax = capitalGainsTax + solidaritySurcharge;
|
|
40
|
+
const breakdowns = [
|
|
41
|
+
{
|
|
42
|
+
from: '0',
|
|
43
|
+
to: 'All',
|
|
44
|
+
rate: this._rules.flatTaxRate,
|
|
45
|
+
amount: capitalGainsTax,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
from: 'CGT',
|
|
49
|
+
to: 'Solidarity',
|
|
50
|
+
rate: this._rules.solidaritySurchargeRate,
|
|
51
|
+
amount: solidaritySurcharge,
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
return {
|
|
55
|
+
taxableGain,
|
|
56
|
+
capitalGainsTax,
|
|
57
|
+
solidaritySurcharge,
|
|
58
|
+
totalTax,
|
|
59
|
+
effectiveRate: gain > 0 ? (totalTax / gain) * 100 : 0,
|
|
60
|
+
breakdowns,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.GermanyCapitalGainsServiceImpl = GermanyCapitalGainsServiceImpl;
|
|
65
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiR2VybWFueUNhcGl0YWxHYWluc1NlcnZpY2VJbXBsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NhcGl0YWwtZ2FpbnMvZ2VybWFueS9HZXJtYW55Q2FwaXRhbEdhaW5zU2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsTUFBYSw4QkFBOEI7SUFJdkMsWUFBWSxLQUFZLEVBQUUsS0FBWTtRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsU0FBUztRQUNMLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBRXJDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ1osT0FBTztnQkFDSCxXQUFXLEVBQUUsQ0FBQztnQkFDZCxlQUFlLEVBQUUsQ0FBQztnQkFDbEIsbUJBQW1CLEVBQUUsQ0FBQztnQkFDdEIsUUFBUSxFQUFFLENBQUM7Z0JBQ1gsYUFBYSxFQUFFLENBQUM7Z0JBQ2hCLFVBQVUsRUFBRSxFQUFFO2FBQ2pCLENBQUM7UUFDTixDQUFDO1FBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFcEUsSUFBSSxXQUFXLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDbkIsT0FBTztnQkFDSCxXQUFXLEVBQUUsQ0FBQztnQkFDZCxlQUFlLEVBQUUsQ0FBQztnQkFDbEIsbUJBQW1CLEVBQUUsQ0FBQztnQkFDdEIsUUFBUSxFQUFFLENBQUM7Z0JBQ1gsYUFBYSxFQUFFLENBQUM7Z0JBQ2hCLFVBQVUsRUFBRSxDQUFDO3dCQUNULElBQUksRUFBRSxHQUFHO3dCQUNULEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFO3dCQUNwQyxJQUFJLEVBQUUsQ0FBQzt3QkFDUCxNQUFNLEVBQUUsQ0FBQztxQkFDWixDQUFDO2FBQ0wsQ0FBQztRQUNOLENBQUM7UUFFRCxNQUFNLGVBQWUsR0FBRyxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUM7UUFDOUQsTUFBTSxtQkFBbUIsR0FBRyxlQUFlLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQztRQUNsRixNQUFNLFFBQVEsR0FBRyxlQUFlLEdBQUcsbUJBQW1CLENBQUM7UUFFdkQsTUFBTSxVQUFVLEdBQWdCO1lBQzVCO2dCQUNJLElBQUksRUFBRSxHQUFHO2dCQUNULEVBQUUsRUFBRSxLQUFLO2dCQUNULElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVc7Z0JBQzdCLE1BQU0sRUFBRSxlQUFlO2FBQzFCO1lBQ0Q7Z0JBQ0ksSUFBSSxFQUFFLEtBQUs7Z0JBQ1gsRUFBRSxFQUFFLFlBQVk7Z0JBQ2hCLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUF1QjtnQkFDekMsTUFBTSxFQUFFLG1CQUFtQjthQUM5QjtTQUNKLENBQUM7UUFFRixPQUFPO1lBQ0gsV0FBVztZQUNYLGVBQWU7WUFDZixtQkFBbUI7WUFDbkIsUUFBUTtZQUNSLGFBQWEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckQsVUFBVTtTQUNiLENBQUM7SUFDTixDQUFDO0NBQ0o7QUFyRUQsd0VBcUVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQnJlYWtkb3duIH0gZnJvbSBcIi4uL2RvbWFpbi90eXBlc1wiO1xuaW1wb3J0IHsgR2VybWFueUNhcGl0YWxHYWluc1NlcnZpY2UgfSBmcm9tIFwiLi9HZXJtYW55Q2FwaXRhbEdhaW5zU2VydmljZVwiO1xuaW1wb3J0IHsgSW5wdXQsIFJlc3VsdCwgUnVsZXMgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIEdlcm1hbnlDYXBpdGFsR2FpbnNTZXJ2aWNlSW1wbCBpbXBsZW1lbnRzIEdlcm1hbnlDYXBpdGFsR2FpbnNTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF9pbnB1dDogSW5wdXQ7XG4gICAgcHJpdmF0ZSBfcnVsZXM6IFJ1bGVzO1xuXG4gICAgY29uc3RydWN0b3IoaW5wdXQ6IElucHV0LCBydWxlczogUnVsZXMpIHtcbiAgICAgICAgdGhpcy5faW5wdXQgPSBpbnB1dDtcbiAgICAgICAgdGhpcy5fcnVsZXMgPSBydWxlcztcbiAgICB9XG5cbiAgICBjYWxjdWxhdGUoKTogUmVzdWx0IHtcbiAgICAgICAgY29uc3QgZ2FpbiA9IHRoaXMuX2lucHV0LmNhcGl0YWxHYWluO1xuXG4gICAgICAgIGlmIChnYWluIDw9IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdGF4YWJsZUdhaW46IDAsXG4gICAgICAgICAgICAgICAgY2FwaXRhbEdhaW5zVGF4OiAwLFxuICAgICAgICAgICAgICAgIHNvbGlkYXJpdHlTdXJjaGFyZ2U6IDAsXG4gICAgICAgICAgICAgICAgdG90YWxUYXg6IDAsXG4gICAgICAgICAgICAgICAgZWZmZWN0aXZlUmF0ZTogMCxcbiAgICAgICAgICAgICAgICBicmVha2Rvd25zOiBbXSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0YXhhYmxlR2FpbiA9IE1hdGgubWF4KDAsIGdhaW4gLSB0aGlzLl9ydWxlcy5hbm51YWxFeGVtcHRpb24pO1xuXG4gICAgICAgIGlmICh0YXhhYmxlR2FpbiA8PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHRheGFibGVHYWluOiAwLFxuICAgICAgICAgICAgICAgIGNhcGl0YWxHYWluc1RheDogMCxcbiAgICAgICAgICAgICAgICBzb2xpZGFyaXR5U3VyY2hhcmdlOiAwLFxuICAgICAgICAgICAgICAgIHRvdGFsVGF4OiAwLFxuICAgICAgICAgICAgICAgIGVmZmVjdGl2ZVJhdGU6IDAsXG4gICAgICAgICAgICAgICAgYnJlYWtkb3duczogW3tcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogJzAnLFxuICAgICAgICAgICAgICAgICAgICB0bzogYCR7dGhpcy5fcnVsZXMuYW5udWFsRXhlbXB0aW9ufWAsXG4gICAgICAgICAgICAgICAgICAgIHJhdGU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICAgICAgICB9XSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjYXBpdGFsR2FpbnNUYXggPSB0YXhhYmxlR2FpbiAqIHRoaXMuX3J1bGVzLmZsYXRUYXhSYXRlO1xuICAgICAgICBjb25zdCBzb2xpZGFyaXR5U3VyY2hhcmdlID0gY2FwaXRhbEdhaW5zVGF4ICogdGhpcy5fcnVsZXMuc29saWRhcml0eVN1cmNoYXJnZVJhdGU7XG4gICAgICAgIGNvbnN0IHRvdGFsVGF4ID0gY2FwaXRhbEdhaW5zVGF4ICsgc29saWRhcml0eVN1cmNoYXJnZTtcblxuICAgICAgICBjb25zdCBicmVha2Rvd25zOiBCcmVha2Rvd25bXSA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiAnMCcsXG4gICAgICAgICAgICAgICAgdG86ICdBbGwnLFxuICAgICAgICAgICAgICAgIHJhdGU6IHRoaXMuX3J1bGVzLmZsYXRUYXhSYXRlLFxuICAgICAgICAgICAgICAgIGFtb3VudDogY2FwaXRhbEdhaW5zVGF4LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmcm9tOiAnQ0dUJyxcbiAgICAgICAgICAgICAgICB0bzogJ1NvbGlkYXJpdHknLFxuICAgICAgICAgICAgICAgIHJhdGU6IHRoaXMuX3J1bGVzLnNvbGlkYXJpdHlTdXJjaGFyZ2VSYXRlLFxuICAgICAgICAgICAgICAgIGFtb3VudDogc29saWRhcml0eVN1cmNoYXJnZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRheGFibGVHYWluLFxuICAgICAgICAgICAgY2FwaXRhbEdhaW5zVGF4LFxuICAgICAgICAgICAgc29saWRhcml0eVN1cmNoYXJnZSxcbiAgICAgICAgICAgIHRvdGFsVGF4LFxuICAgICAgICAgICAgZWZmZWN0aXZlUmF0ZTogZ2FpbiA+IDAgPyAodG90YWxUYXggLyBnYWluKSAqIDEwMCA6IDAsXG4gICAgICAgICAgICBicmVha2Rvd25zLFxuICAgICAgICB9O1xuICAgIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9nZXJtYW55L2RvbWFpbi90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQnJlYWtkb3duIH0gZnJvbSBcIi4uLy4uL2RvbWFpbi90eXBlc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bGVzIHtcbiAgICBmbGF0VGF4UmF0ZTogbnVtYmVyO1xuICAgIHNvbGlkYXJpdHlTdXJjaGFyZ2VSYXRlOiBudW1iZXI7XG4gICAgYW5udWFsRXhlbXB0aW9uOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXQge1xuICAgIGNhcGl0YWxHYWluOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdWx0IHtcbiAgICB0YXhhYmxlR2FpbjogbnVtYmVyO1xuICAgIGNhcGl0YWxHYWluc1RheDogbnVtYmVyO1xuICAgIHNvbGlkYXJpdHlTdXJjaGFyZ2U6IG51bWJlcjtcbiAgICB0b3RhbFRheDogbnVtYmVyO1xuICAgIGVmZmVjdGl2ZVJhdGU6IG51bWJlcjtcbiAgICBicmVha2Rvd25zOiBCcmVha2Rvd25bXTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU291dGhBZnJpY2FDYXBpdGFsR2FpbnNTZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NhcGl0YWwtZ2FpbnMvc291dGgtYWZyaWNhL1NvdXRoQWZyaWNhQ2FwaXRhbEdhaW5zU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUmVzdWx0IH0gZnJvbSBcIi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU291dGhBZnJpY2FDYXBpdGFsR2FpbnNTZXJ2aWNlIHtcbiAgICBjYWxjdWxhdGUoKTogUmVzdWx0O1xufVxuIl19
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SouthAfricaCapitalGainsServiceImpl = void 0;
|
|
4
|
+
class SouthAfricaCapitalGainsServiceImpl {
|
|
5
|
+
constructor(input, rules) {
|
|
6
|
+
this._input = input;
|
|
7
|
+
this._rules = rules;
|
|
8
|
+
}
|
|
9
|
+
calculate() {
|
|
10
|
+
const gain = this._input.capitalGain;
|
|
11
|
+
if (gain <= 0) {
|
|
12
|
+
return { taxableGain: 0, capitalGainsTax: 0, effectiveRate: 0, breakdowns: [] };
|
|
13
|
+
}
|
|
14
|
+
const netGain = Math.max(0, gain - this._rules.annualExclusion);
|
|
15
|
+
const taxableGain = netGain * this._rules.inclusionRate;
|
|
16
|
+
if (taxableGain <= 0) {
|
|
17
|
+
return {
|
|
18
|
+
taxableGain: 0,
|
|
19
|
+
capitalGainsTax: 0,
|
|
20
|
+
effectiveRate: 0,
|
|
21
|
+
breakdowns: [{
|
|
22
|
+
from: '0',
|
|
23
|
+
to: `${this._rules.annualExclusion}`,
|
|
24
|
+
rate: 0,
|
|
25
|
+
amount: 0,
|
|
26
|
+
}],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const otherIncome = this._input.totalTaxableIncome - gain;
|
|
30
|
+
const { tax, breakdowns } = this.applyBrackets(taxableGain, otherIncome, this._rules.taxBrackets);
|
|
31
|
+
return {
|
|
32
|
+
taxableGain,
|
|
33
|
+
capitalGainsTax: tax,
|
|
34
|
+
effectiveRate: gain > 0 ? (tax / gain) * 100 : 0,
|
|
35
|
+
breakdowns,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
applyBrackets(taxableGain, otherIncome, brackets) {
|
|
39
|
+
let tax = 0;
|
|
40
|
+
const breakdowns = [];
|
|
41
|
+
let remaining = taxableGain;
|
|
42
|
+
let incomeUsed = otherIncome;
|
|
43
|
+
for (const bracket of brackets) {
|
|
44
|
+
if (remaining <= 0)
|
|
45
|
+
break;
|
|
46
|
+
const upper = bracket.to ?? Infinity;
|
|
47
|
+
if (incomeUsed >= upper)
|
|
48
|
+
continue;
|
|
49
|
+
const bracketStart = Math.max(bracket.from, incomeUsed);
|
|
50
|
+
const bracketSpace = upper - bracketStart;
|
|
51
|
+
const taxable = Math.min(bracketSpace, remaining);
|
|
52
|
+
if (taxable > 0) {
|
|
53
|
+
const bracketTax = taxable * bracket.rate;
|
|
54
|
+
tax += bracketTax;
|
|
55
|
+
remaining -= taxable;
|
|
56
|
+
incomeUsed += taxable;
|
|
57
|
+
breakdowns.push({
|
|
58
|
+
from: `${bracket.from}`,
|
|
59
|
+
to: `${bracket.to ?? 'Above'}`,
|
|
60
|
+
rate: bracket.rate,
|
|
61
|
+
amount: bracketTax,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { tax, breakdowns };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.SouthAfricaCapitalGainsServiceImpl = SouthAfricaCapitalGainsServiceImpl;
|
|
69
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU291dGhBZnJpY2FDYXBpdGFsR2FpbnNTZXJ2aWNlSW1wbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jYXBpdGFsLWdhaW5zL3NvdXRoLWFmcmljYS9Tb3V0aEFmcmljYUNhcGl0YWxHYWluc1NlcnZpY2VJbXBsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUlBLE1BQWEsa0NBQWtDO0lBSTNDLFlBQVksS0FBWSxFQUFFLEtBQVk7UUFDbEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDcEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUVELFNBQVM7UUFDTCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztRQUVyQyxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNaLE9BQU8sRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLGVBQWUsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDcEYsQ0FBQztRQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sV0FBVyxHQUFHLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQztRQUV4RCxJQUFJLFdBQVcsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNuQixPQUFPO2dCQUNILFdBQVcsRUFBRSxDQUFDO2dCQUNkLGVBQWUsRUFBRSxDQUFDO2dCQUNsQixhQUFhLEVBQUUsQ0FBQztnQkFDaEIsVUFBVSxFQUFFLENBQUM7d0JBQ1QsSUFBSSxFQUFFLEdBQUc7d0JBQ1QsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLEVBQUU7d0JBQ3BDLElBQUksRUFBRSxDQUFDO3dCQUNQLE1BQU0sRUFBRSxDQUFDO3FCQUNaLENBQUM7YUFDTCxDQUFDO1FBQ04sQ0FBQztRQUVELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO1FBQzFELE1BQU0sRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFbEcsT0FBTztZQUNILFdBQVc7WUFDWCxlQUFlLEVBQUUsR0FBRztZQUNwQixhQUFhLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hELFVBQVU7U0FDYixDQUFDO0lBQ04sQ0FBQztJQUVPLGFBQWEsQ0FDakIsV0FBbUIsRUFDbkIsV0FBbUIsRUFDbkIsUUFBc0I7UUFFdEIsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1osTUFBTSxVQUFVLEdBQWdCLEVBQUUsQ0FBQztRQUNuQyxJQUFJLFNBQVMsR0FBRyxXQUFXLENBQUM7UUFDNUIsSUFBSSxVQUFVLEdBQUcsV0FBVyxDQUFDO1FBRTdCLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7WUFDN0IsSUFBSSxTQUFTLElBQUksQ0FBQztnQkFBRSxNQUFNO1lBRTFCLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxFQUFFLElBQUksUUFBUSxDQUFDO1lBRXJDLElBQUksVUFBVSxJQUFJLEtBQUs7Z0JBQUUsU0FBUztZQUVsQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDeEQsTUFBTSxZQUFZLEdBQUcsS0FBSyxHQUFHLFlBQVksQ0FBQztZQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsQ0FBQztZQUVsRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDZCxNQUFNLFVBQVUsR0FBRyxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztnQkFDMUMsR0FBRyxJQUFJLFVBQVUsQ0FBQztnQkFDbEIsU0FBUyxJQUFJLE9BQU8sQ0FBQztnQkFDckIsVUFBVSxJQUFJLE9BQU8sQ0FBQztnQkFFdEIsVUFBVSxDQUFDLElBQUksQ0FBQztvQkFDWixJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxFQUFFO29CQUN2QixFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUMsRUFBRSxJQUFJLE9BQU8sRUFBRTtvQkFDOUIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO29CQUNsQixNQUFNLEVBQUUsVUFBVTtpQkFDckIsQ0FBQyxDQUFDO1lBQ1AsQ0FBQztRQUNMLENBQUM7UUFFRCxPQUFPLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxDQUFDO0lBQy9CLENBQUM7Q0FDSjtBQWxGRCxnRkFrRkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmVha2Rvd24gfSBmcm9tIFwiLi4vZG9tYWluL3R5cGVzXCI7XG5pbXBvcnQgeyBTb3V0aEFmcmljYUNhcGl0YWxHYWluc1NlcnZpY2UgfSBmcm9tIFwiLi9Tb3V0aEFmcmljYUNhcGl0YWxHYWluc1NlcnZpY2VcIjtcbmltcG9ydCB7IElucHV0LCBSZXN1bHQsIFJ1bGVzLCBUYXhCcmFja2V0IH0gZnJvbSBcIi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBTb3V0aEFmcmljYUNhcGl0YWxHYWluc1NlcnZpY2VJbXBsIGltcGxlbWVudHMgU291dGhBZnJpY2FDYXBpdGFsR2FpbnNTZXJ2aWNlIHtcbiAgICBwcml2YXRlIF9pbnB1dDogSW5wdXQ7XG4gICAgcHJpdmF0ZSBfcnVsZXM6IFJ1bGVzO1xuXG4gICAgY29uc3RydWN0b3IoaW5wdXQ6IElucHV0LCBydWxlczogUnVsZXMpIHtcbiAgICAgICAgdGhpcy5faW5wdXQgPSBpbnB1dDtcbiAgICAgICAgdGhpcy5fcnVsZXMgPSBydWxlcztcbiAgICB9XG5cbiAgICBjYWxjdWxhdGUoKTogUmVzdWx0IHtcbiAgICAgICAgY29uc3QgZ2FpbiA9IHRoaXMuX2lucHV0LmNhcGl0YWxHYWluO1xuXG4gICAgICAgIGlmIChnYWluIDw9IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IHRheGFibGVHYWluOiAwLCBjYXBpdGFsR2FpbnNUYXg6IDAsIGVmZmVjdGl2ZVJhdGU6IDAsIGJyZWFrZG93bnM6IFtdIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXRHYWluID0gTWF0aC5tYXgoMCwgZ2FpbiAtIHRoaXMuX3J1bGVzLmFubnVhbEV4Y2x1c2lvbik7XG4gICAgICAgIGNvbnN0IHRheGFibGVHYWluID0gbmV0R2FpbiAqIHRoaXMuX3J1bGVzLmluY2x1c2lvblJhdGU7XG5cbiAgICAgICAgaWYgKHRheGFibGVHYWluIDw9IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdGF4YWJsZUdhaW46IDAsXG4gICAgICAgICAgICAgICAgY2FwaXRhbEdhaW5zVGF4OiAwLFxuICAgICAgICAgICAgICAgIGVmZmVjdGl2ZVJhdGU6IDAsXG4gICAgICAgICAgICAgICAgYnJlYWtkb3duczogW3tcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogJzAnLFxuICAgICAgICAgICAgICAgICAgICB0bzogYCR7dGhpcy5fcnVsZXMuYW5udWFsRXhjbHVzaW9ufWAsXG4gICAgICAgICAgICAgICAgICAgIHJhdGU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgICAgICAgICB9XSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvdGhlckluY29tZSA9IHRoaXMuX2lucHV0LnRvdGFsVGF4YWJsZUluY29tZSAtIGdhaW47XG4gICAgICAgIGNvbnN0IHsgdGF4LCBicmVha2Rvd25zIH0gPSB0aGlzLmFwcGx5QnJhY2tldHModGF4YWJsZUdhaW4sIG90aGVySW5jb21lLCB0aGlzLl9ydWxlcy50YXhCcmFja2V0cyk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRheGFibGVHYWluLFxuICAgICAgICAgICAgY2FwaXRhbEdhaW5zVGF4OiB0YXgsXG4gICAgICAgICAgICBlZmZlY3RpdmVSYXRlOiBnYWluID4gMCA/ICh0YXggLyBnYWluKSAqIDEwMCA6IDAsXG4gICAgICAgICAgICBicmVha2Rvd25zLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgYXBwbHlCcmFja2V0cyhcbiAgICAgICAgdGF4YWJsZUdhaW46IG51bWJlcixcbiAgICAgICAgb3RoZXJJbmNvbWU6IG51bWJlcixcbiAgICAgICAgYnJhY2tldHM6IFRheEJyYWNrZXRbXSxcbiAgICApOiB7IHRheDogbnVtYmVyOyBicmVha2Rvd25zOiBCcmVha2Rvd25bXSB9IHtcbiAgICAgICAgbGV0IHRheCA9IDA7XG4gICAgICAgIGNvbnN0IGJyZWFrZG93bnM6IEJyZWFrZG93bltdID0gW107XG4gICAgICAgIGxldCByZW1haW5pbmcgPSB0YXhhYmxlR2FpbjtcbiAgICAgICAgbGV0IGluY29tZVVzZWQgPSBvdGhlckluY29tZTtcblxuICAgICAgICBmb3IgKGNvbnN0IGJyYWNrZXQgb2YgYnJhY2tldHMpIHtcbiAgICAgICAgICAgIGlmIChyZW1haW5pbmcgPD0gMCkgYnJlYWs7XG5cbiAgICAgICAgICAgIGNvbnN0IHVwcGVyID0gYnJhY2tldC50byA/PyBJbmZpbml0eTtcblxuICAgICAgICAgICAgaWYgKGluY29tZVVzZWQgPj0gdXBwZXIpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgICBjb25zdCBicmFja2V0U3RhcnQgPSBNYXRoLm1heChicmFja2V0LmZyb20sIGluY29tZVVzZWQpO1xuICAgICAgICAgICAgY29uc3QgYnJhY2tldFNwYWNlID0gdXBwZXIgLSBicmFja2V0U3RhcnQ7XG4gICAgICAgICAgICBjb25zdCB0YXhhYmxlID0gTWF0aC5taW4oYnJhY2tldFNwYWNlLCByZW1haW5pbmcpO1xuXG4gICAgICAgICAgICBpZiAodGF4YWJsZSA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBicmFja2V0VGF4ID0gdGF4YWJsZSAqIGJyYWNrZXQucmF0ZTtcbiAgICAgICAgICAgICAgICB0YXggKz0gYnJhY2tldFRheDtcbiAgICAgICAgICAgICAgICByZW1haW5pbmcgLT0gdGF4YWJsZTtcbiAgICAgICAgICAgICAgICBpbmNvbWVVc2VkICs9IHRheGFibGU7XG5cbiAgICAgICAgICAgICAgICBicmVha2Rvd25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBmcm9tOiBgJHticmFja2V0LmZyb219YCxcbiAgICAgICAgICAgICAgICAgICAgdG86IGAke2JyYWNrZXQudG8gPz8gJ0Fib3ZlJ31gLFxuICAgICAgICAgICAgICAgICAgICByYXRlOiBicmFja2V0LnJhdGUsXG4gICAgICAgICAgICAgICAgICAgIGFtb3VudDogYnJhY2tldFRheCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IHRheCwgYnJlYWtkb3ducyB9O1xuICAgIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy9zb3V0aC1hZnJpY2EvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmVha2Rvd24gfSBmcm9tIFwiLi4vLi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGF4QnJhY2tldCB7XG4gICAgZnJvbTogbnVtYmVyO1xuICAgIHRvOiBudW1iZXIgfCBudWxsO1xuICAgIHJhdGU6IG51bWJlcjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSdWxlcyB7XG4gICAgaW5jbHVzaW9uUmF0ZTogbnVtYmVyO1xuICAgIGFubnVhbEV4Y2x1c2lvbjogbnVtYmVyO1xuICAgIHRheEJyYWNrZXRzOiBUYXhCcmFja2V0W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXQge1xuICAgIGNhcGl0YWxHYWluOiBudW1iZXI7XG4gICAgdG90YWxUYXhhYmxlSW5jb21lOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdWx0IHtcbiAgICB0YXhhYmxlR2FpbjogbnVtYmVyO1xuICAgIGNhcGl0YWxHYWluc1RheDogbnVtYmVyO1xuICAgIGVmZmVjdGl2ZVJhdGU6IG51bWJlcjtcbiAgICBicmVha2Rvd25zOiBCcmVha2Rvd25bXTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVUtDYXBpdGFsR2FpbnNTZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NhcGl0YWwtZ2FpbnMvdWsvVUtDYXBpdGFsR2FpbnNTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXN1bHQgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBVS0NhcGl0YWxHYWluc1NlcnZpY2Uge1xuICAgIGNhbGN1bGF0ZSgpOiBSZXN1bHQ7XG59XG4iXX0=
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UKCapitalGainsServiceImpl = void 0;
|
|
4
|
+
class UKCapitalGainsServiceImpl {
|
|
5
|
+
constructor(input, rules) {
|
|
6
|
+
this._input = input;
|
|
7
|
+
this._rules = rules;
|
|
8
|
+
}
|
|
9
|
+
calculate() {
|
|
10
|
+
const gain = this._input.capitalGain;
|
|
11
|
+
if (gain <= 0) {
|
|
12
|
+
return { taxableGain: 0, capitalGainsTax: 0, effectiveRate: 0, breakdowns: [] };
|
|
13
|
+
}
|
|
14
|
+
const taxableGain = Math.max(0, gain - this._rules.annualExemption);
|
|
15
|
+
if (taxableGain <= 0) {
|
|
16
|
+
return {
|
|
17
|
+
taxableGain: 0,
|
|
18
|
+
capitalGainsTax: 0,
|
|
19
|
+
effectiveRate: 0,
|
|
20
|
+
breakdowns: [{
|
|
21
|
+
from: '0',
|
|
22
|
+
to: `${this._rules.annualExemption}`,
|
|
23
|
+
rate: 0,
|
|
24
|
+
amount: 0,
|
|
25
|
+
}],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const basicRateRemaining = Math.max(0, this._rules.basicRateLimit - this._input.totalTaxableIncome);
|
|
29
|
+
const breakdowns = [];
|
|
30
|
+
let tax = 0;
|
|
31
|
+
if (basicRateRemaining > 0) {
|
|
32
|
+
const basicRateGain = Math.min(taxableGain, basicRateRemaining);
|
|
33
|
+
const basicTax = basicRateGain * this._rules.basicRate;
|
|
34
|
+
tax += basicTax;
|
|
35
|
+
breakdowns.push({
|
|
36
|
+
from: '0',
|
|
37
|
+
to: `${basicRateRemaining}`,
|
|
38
|
+
rate: this._rules.basicRate,
|
|
39
|
+
amount: basicTax,
|
|
40
|
+
});
|
|
41
|
+
const higherRateGain = taxableGain - basicRateGain;
|
|
42
|
+
if (higherRateGain > 0) {
|
|
43
|
+
const higherTax = higherRateGain * this._rules.higherRate;
|
|
44
|
+
tax += higherTax;
|
|
45
|
+
breakdowns.push({
|
|
46
|
+
from: `${basicRateRemaining}`,
|
|
47
|
+
to: 'Above',
|
|
48
|
+
rate: this._rules.higherRate,
|
|
49
|
+
amount: higherTax,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const higherTax = taxableGain * this._rules.higherRate;
|
|
55
|
+
tax += higherTax;
|
|
56
|
+
breakdowns.push({
|
|
57
|
+
from: '0',
|
|
58
|
+
to: 'Above',
|
|
59
|
+
rate: this._rules.higherRate,
|
|
60
|
+
amount: higherTax,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
taxableGain,
|
|
65
|
+
capitalGainsTax: tax,
|
|
66
|
+
effectiveRate: gain > 0 ? (tax / gain) * 100 : 0,
|
|
67
|
+
breakdowns,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.UKCapitalGainsServiceImpl = UKCapitalGainsServiceImpl;
|
|
72
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVUtDYXBpdGFsR2FpbnNTZXJ2aWNlSW1wbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jYXBpdGFsLWdhaW5zL3VrL1VLQ2FwaXRhbEdhaW5zU2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsTUFBYSx5QkFBeUI7SUFJbEMsWUFBWSxLQUFZLEVBQUUsS0FBWTtRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsU0FBUztRQUNMLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBRXJDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ1osT0FBTyxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsZUFBZSxFQUFFLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNwRixDQUFDO1FBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFcEUsSUFBSSxXQUFXLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDbkIsT0FBTztnQkFDSCxXQUFXLEVBQUUsQ0FBQztnQkFDZCxlQUFlLEVBQUUsQ0FBQztnQkFDbEIsYUFBYSxFQUFFLENBQUM7Z0JBQ2hCLFVBQVUsRUFBRSxDQUFDO3dCQUNULElBQUksRUFBRSxHQUFHO3dCQUNULEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxFQUFFO3dCQUNwQyxJQUFJLEVBQUUsQ0FBQzt3QkFDUCxNQUFNLEVBQUUsQ0FBQztxQkFDWixDQUFDO2FBQ0wsQ0FBQztRQUNOLENBQUM7UUFFRCxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNwRyxNQUFNLFVBQVUsR0FBZ0IsRUFBRSxDQUFDO1FBQ25DLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUVaLElBQUksa0JBQWtCLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztZQUNoRSxNQUFNLFFBQVEsR0FBRyxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7WUFDdkQsR0FBRyxJQUFJLFFBQVEsQ0FBQztZQUVoQixVQUFVLENBQUMsSUFBSSxDQUFDO2dCQUNaLElBQUksRUFBRSxHQUFHO2dCQUNULEVBQUUsRUFBRSxHQUFHLGtCQUFrQixFQUFFO2dCQUMzQixJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTO2dCQUMzQixNQUFNLEVBQUUsUUFBUTthQUNuQixDQUFDLENBQUM7WUFFSCxNQUFNLGNBQWMsR0FBRyxXQUFXLEdBQUcsYUFBYSxDQUFDO1lBQ25ELElBQUksY0FBYyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNyQixNQUFNLFNBQVMsR0FBRyxjQUFjLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7Z0JBQzFELEdBQUcsSUFBSSxTQUFTLENBQUM7Z0JBRWpCLFVBQVUsQ0FBQyxJQUFJLENBQUM7b0JBQ1osSUFBSSxFQUFFLEdBQUcsa0JBQWtCLEVBQUU7b0JBQzdCLEVBQUUsRUFBRSxPQUFPO29CQUNYLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVU7b0JBQzVCLE1BQU0sRUFBRSxTQUFTO2lCQUNwQixDQUFDLENBQUM7WUFDUCxDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDSixNQUFNLFNBQVMsR0FBRyxXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDdkQsR0FBRyxJQUFJLFNBQVMsQ0FBQztZQUVqQixVQUFVLENBQUMsSUFBSSxDQUFDO2dCQUNaLElBQUksRUFBRSxHQUFHO2dCQUNULEVBQUUsRUFBRSxPQUFPO2dCQUNYLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVU7Z0JBQzVCLE1BQU0sRUFBRSxTQUFTO2FBQ3BCLENBQUMsQ0FBQztRQUNQLENBQUM7UUFFRCxPQUFPO1lBQ0gsV0FBVztZQUNYLGVBQWUsRUFBRSxHQUFHO1lBQ3BCLGFBQWEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEQsVUFBVTtTQUNiLENBQUM7SUFDTixDQUFDO0NBQ0o7QUEvRUQsOERBK0VDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQnJlYWtkb3duIH0gZnJvbSBcIi4uL2RvbWFpbi90eXBlc1wiO1xuaW1wb3J0IHsgVUtDYXBpdGFsR2FpbnNTZXJ2aWNlIH0gZnJvbSBcIi4vVUtDYXBpdGFsR2FpbnNTZXJ2aWNlXCI7XG5pbXBvcnQgeyBJbnB1dCwgUmVzdWx0LCBSdWxlcyB9IGZyb20gXCIuL2RvbWFpbi90eXBlc1wiO1xuXG5leHBvcnQgY2xhc3MgVUtDYXBpdGFsR2FpbnNTZXJ2aWNlSW1wbCBpbXBsZW1lbnRzIFVLQ2FwaXRhbEdhaW5zU2VydmljZSB7XG4gICAgcHJpdmF0ZSBfaW5wdXQ6IElucHV0O1xuICAgIHByaXZhdGUgX3J1bGVzOiBSdWxlcztcblxuICAgIGNvbnN0cnVjdG9yKGlucHV0OiBJbnB1dCwgcnVsZXM6IFJ1bGVzKSB7XG4gICAgICAgIHRoaXMuX2lucHV0ID0gaW5wdXQ7XG4gICAgICAgIHRoaXMuX3J1bGVzID0gcnVsZXM7XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlKCk6IFJlc3VsdCB7XG4gICAgICAgIGNvbnN0IGdhaW4gPSB0aGlzLl9pbnB1dC5jYXBpdGFsR2FpbjtcblxuICAgICAgICBpZiAoZ2FpbiA8PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4geyB0YXhhYmxlR2FpbjogMCwgY2FwaXRhbEdhaW5zVGF4OiAwLCBlZmZlY3RpdmVSYXRlOiAwLCBicmVha2Rvd25zOiBbXSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGF4YWJsZUdhaW4gPSBNYXRoLm1heCgwLCBnYWluIC0gdGhpcy5fcnVsZXMuYW5udWFsRXhlbXB0aW9uKTtcblxuICAgICAgICBpZiAodGF4YWJsZUdhaW4gPD0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB0YXhhYmxlR2FpbjogMCxcbiAgICAgICAgICAgICAgICBjYXBpdGFsR2FpbnNUYXg6IDAsXG4gICAgICAgICAgICAgICAgZWZmZWN0aXZlUmF0ZTogMCxcbiAgICAgICAgICAgICAgICBicmVha2Rvd25zOiBbe1xuICAgICAgICAgICAgICAgICAgICBmcm9tOiAnMCcsXG4gICAgICAgICAgICAgICAgICAgIHRvOiBgJHt0aGlzLl9ydWxlcy5hbm51YWxFeGVtcHRpb259YCxcbiAgICAgICAgICAgICAgICAgICAgcmF0ZTogMCxcbiAgICAgICAgICAgICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICAgICAgICAgIH1dLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGJhc2ljUmF0ZVJlbWFpbmluZyA9IE1hdGgubWF4KDAsIHRoaXMuX3J1bGVzLmJhc2ljUmF0ZUxpbWl0IC0gdGhpcy5faW5wdXQudG90YWxUYXhhYmxlSW5jb21lKTtcbiAgICAgICAgY29uc3QgYnJlYWtkb3duczogQnJlYWtkb3duW10gPSBbXTtcbiAgICAgICAgbGV0IHRheCA9IDA7XG5cbiAgICAgICAgaWYgKGJhc2ljUmF0ZVJlbWFpbmluZyA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGJhc2ljUmF0ZUdhaW4gPSBNYXRoLm1pbih0YXhhYmxlR2FpbiwgYmFzaWNSYXRlUmVtYWluaW5nKTtcbiAgICAgICAgICAgIGNvbnN0IGJhc2ljVGF4ID0gYmFzaWNSYXRlR2FpbiAqIHRoaXMuX3J1bGVzLmJhc2ljUmF0ZTtcbiAgICAgICAgICAgIHRheCArPSBiYXNpY1RheDtcblxuICAgICAgICAgICAgYnJlYWtkb3ducy5wdXNoKHtcbiAgICAgICAgICAgICAgICBmcm9tOiAnMCcsXG4gICAgICAgICAgICAgICAgdG86IGAke2Jhc2ljUmF0ZVJlbWFpbmluZ31gLFxuICAgICAgICAgICAgICAgIHJhdGU6IHRoaXMuX3J1bGVzLmJhc2ljUmF0ZSxcbiAgICAgICAgICAgICAgICBhbW91bnQ6IGJhc2ljVGF4LFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IGhpZ2hlclJhdGVHYWluID0gdGF4YWJsZUdhaW4gLSBiYXNpY1JhdGVHYWluO1xuICAgICAgICAgICAgaWYgKGhpZ2hlclJhdGVHYWluID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhpZ2hlclRheCA9IGhpZ2hlclJhdGVHYWluICogdGhpcy5fcnVsZXMuaGlnaGVyUmF0ZTtcbiAgICAgICAgICAgICAgICB0YXggKz0gaGlnaGVyVGF4O1xuXG4gICAgICAgICAgICAgICAgYnJlYWtkb3ducy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbTogYCR7YmFzaWNSYXRlUmVtYWluaW5nfWAsXG4gICAgICAgICAgICAgICAgICAgIHRvOiAnQWJvdmUnLFxuICAgICAgICAgICAgICAgICAgICByYXRlOiB0aGlzLl9ydWxlcy5oaWdoZXJSYXRlLFxuICAgICAgICAgICAgICAgICAgICBhbW91bnQ6IGhpZ2hlclRheCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGhpZ2hlclRheCA9IHRheGFibGVHYWluICogdGhpcy5fcnVsZXMuaGlnaGVyUmF0ZTtcbiAgICAgICAgICAgIHRheCArPSBoaWdoZXJUYXg7XG5cbiAgICAgICAgICAgIGJyZWFrZG93bnMucHVzaCh7XG4gICAgICAgICAgICAgICAgZnJvbTogJzAnLFxuICAgICAgICAgICAgICAgIHRvOiAnQWJvdmUnLFxuICAgICAgICAgICAgICAgIHJhdGU6IHRoaXMuX3J1bGVzLmhpZ2hlclJhdGUsXG4gICAgICAgICAgICAgICAgYW1vdW50OiBoaWdoZXJUYXgsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0YXhhYmxlR2FpbixcbiAgICAgICAgICAgIGNhcGl0YWxHYWluc1RheDogdGF4LFxuICAgICAgICAgICAgZWZmZWN0aXZlUmF0ZTogZ2FpbiA+IDAgPyAodGF4IC8gZ2FpbikgKiAxMDAgOiAwLFxuICAgICAgICAgICAgYnJlYWtkb3ducyxcbiAgICAgICAgfTtcbiAgICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy91ay9kb21haW4vdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJyZWFrZG93biB9IGZyb20gXCIuLi8uLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBSdWxlcyB7XG4gICAgYW5udWFsRXhlbXB0aW9uOiBudW1iZXI7XG4gICAgYmFzaWNSYXRlOiBudW1iZXI7XG4gICAgaGlnaGVyUmF0ZTogbnVtYmVyO1xuICAgIGJhc2ljUmF0ZUxpbWl0OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXQge1xuICAgIGNhcGl0YWxHYWluOiBudW1iZXI7XG4gICAgdG90YWxUYXhhYmxlSW5jb21lOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdWx0IHtcbiAgICB0YXhhYmxlR2FpbjogbnVtYmVyO1xuICAgIGNhcGl0YWxHYWluc1RheDogbnVtYmVyO1xuICAgIGVmZmVjdGl2ZVJhdGU6IG51bWJlcjtcbiAgICBicmVha2Rvd25zOiBCcmVha2Rvd25bXTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVVNBQ2FwaXRhbEdhaW5zU2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jYXBpdGFsLWdhaW5zL3VzYS9VU0FDYXBpdGFsR2FpbnNTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXN1bHQgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBVU0FDYXBpdGFsR2FpbnNTZXJ2aWNlIHtcbiAgICBjYWxjdWxhdGUoKTogUmVzdWx0O1xufVxuIl19
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.USACapitalGainsServiceImpl = void 0;
|
|
4
|
+
class USACapitalGainsServiceImpl {
|
|
5
|
+
constructor(input, rules) {
|
|
6
|
+
this._input = input;
|
|
7
|
+
this._rules = rules;
|
|
8
|
+
}
|
|
9
|
+
calculate() {
|
|
10
|
+
const gain = this._input.capitalGain;
|
|
11
|
+
if (gain <= 0) {
|
|
12
|
+
return { capitalGainsTax: 0, netInvestmentIncomeTax: 0, totalTax: 0, effectiveRate: 0, breakdowns: [] };
|
|
13
|
+
}
|
|
14
|
+
const isLongTerm = this._input.holdingPeriodMonths > 12;
|
|
15
|
+
const brackets = isLongTerm ? this._rules.longTermBrackets : this._rules.shortTermBrackets;
|
|
16
|
+
const { tax, breakdowns } = this.applyBrackets(gain, this._input.totalTaxableIncome, brackets);
|
|
17
|
+
let niit = 0;
|
|
18
|
+
if (this._input.totalTaxableIncome > this._rules.netInvestmentIncomeTax.threshold) {
|
|
19
|
+
niit = gain * this._rules.netInvestmentIncomeTax.rate;
|
|
20
|
+
breakdowns.push({
|
|
21
|
+
from: 'NIIT',
|
|
22
|
+
to: 'All Gain',
|
|
23
|
+
rate: this._rules.netInvestmentIncomeTax.rate,
|
|
24
|
+
amount: niit,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const totalTax = tax + niit;
|
|
28
|
+
return {
|
|
29
|
+
capitalGainsTax: tax,
|
|
30
|
+
netInvestmentIncomeTax: niit,
|
|
31
|
+
totalTax,
|
|
32
|
+
effectiveRate: gain > 0 ? (totalTax / gain) * 100 : 0,
|
|
33
|
+
breakdowns,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
applyBrackets(gain, totalIncome, brackets) {
|
|
37
|
+
let tax = 0;
|
|
38
|
+
const breakdowns = [];
|
|
39
|
+
let remaining = gain;
|
|
40
|
+
let incomeUsed = totalIncome - gain;
|
|
41
|
+
for (const bracket of brackets) {
|
|
42
|
+
if (remaining <= 0)
|
|
43
|
+
break;
|
|
44
|
+
const upper = bracket.to ?? Infinity;
|
|
45
|
+
if (incomeUsed >= upper)
|
|
46
|
+
continue;
|
|
47
|
+
const bracketStart = Math.max(bracket.from, incomeUsed);
|
|
48
|
+
const bracketSpace = upper - bracketStart;
|
|
49
|
+
const taxable = Math.min(bracketSpace, remaining);
|
|
50
|
+
if (taxable > 0) {
|
|
51
|
+
const bracketTax = taxable * bracket.rate;
|
|
52
|
+
tax += bracketTax;
|
|
53
|
+
remaining -= taxable;
|
|
54
|
+
incomeUsed += taxable;
|
|
55
|
+
breakdowns.push({
|
|
56
|
+
from: `${bracket.from}`,
|
|
57
|
+
to: `${bracket.to ?? 'Above'}`,
|
|
58
|
+
rate: bracket.rate,
|
|
59
|
+
amount: bracketTax,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { tax, breakdowns };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.USACapitalGainsServiceImpl = USACapitalGainsServiceImpl;
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVVNBQ2FwaXRhbEdhaW5zU2VydmljZUltcGwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy91c2EvVVNBQ2FwaXRhbEdhaW5zU2VydmljZUltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsTUFBYSwwQkFBMEI7SUFJbkMsWUFBWSxLQUFZLEVBQUUsS0FBWTtRQUNsQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsU0FBUztRQUNMLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDO1FBRXJDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ1osT0FBTyxFQUFFLGVBQWUsRUFBRSxDQUFDLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUM7UUFDNUcsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEdBQUcsRUFBRSxDQUFDO1FBQ3hELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQztRQUUzRixNQUFNLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFFL0YsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsc0JBQXNCLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDaEYsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQztZQUN0RCxVQUFVLENBQUMsSUFBSSxDQUFDO2dCQUNaLElBQUksRUFBRSxNQUFNO2dCQUNaLEVBQUUsRUFBRSxVQUFVO2dCQUNkLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLElBQUk7Z0JBQzdDLE1BQU0sRUFBRSxJQUFJO2FBQ2YsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUM7UUFFNUIsT0FBTztZQUNILGVBQWUsRUFBRSxHQUFHO1lBQ3BCLHNCQUFzQixFQUFFLElBQUk7WUFDNUIsUUFBUTtZQUNSLGFBQWEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDckQsVUFBVTtTQUNiLENBQUM7SUFDTixDQUFDO0lBRU8sYUFBYSxDQUNqQixJQUFZLEVBQ1osV0FBbUIsRUFDbkIsUUFBMkI7UUFFM0IsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1osTUFBTSxVQUFVLEdBQWdCLEVBQUUsQ0FBQztRQUNuQyxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxVQUFVLEdBQUcsV0FBVyxHQUFHLElBQUksQ0FBQztRQUVwQyxLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQzdCLElBQUksU0FBUyxJQUFJLENBQUM7Z0JBQUUsTUFBTTtZQUUxQixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsRUFBRSxJQUFJLFFBQVEsQ0FBQztZQUVyQyxJQUFJLFVBQVUsSUFBSSxLQUFLO2dCQUFFLFNBQVM7WUFFbEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3hELE1BQU0sWUFBWSxHQUFHLEtBQUssR0FBRyxZQUFZLENBQUM7WUFDMUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFbEQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2QsTUFBTSxVQUFVLEdBQUcsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQzFDLEdBQUcsSUFBSSxVQUFVLENBQUM7Z0JBQ2xCLFNBQVMsSUFBSSxPQUFPLENBQUM7Z0JBQ3JCLFVBQVUsSUFBSSxPQUFPLENBQUM7Z0JBRXRCLFVBQVUsQ0FBQyxJQUFJLENBQUM7b0JBQ1osSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLElBQUksRUFBRTtvQkFDdkIsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLEVBQUUsSUFBSSxPQUFPLEVBQUU7b0JBQzlCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtvQkFDbEIsTUFBTSxFQUFFLFVBQVU7aUJBQ3JCLENBQUMsQ0FBQztZQUNQLENBQUM7UUFDTCxDQUFDO1FBRUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUMvQixDQUFDO0NBQ0o7QUFqRkQsZ0VBaUZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQnJlYWtkb3duIH0gZnJvbSBcIi4uL2RvbWFpbi90eXBlc1wiO1xuaW1wb3J0IHsgVVNBQ2FwaXRhbEdhaW5zU2VydmljZSB9IGZyb20gXCIuL1VTQUNhcGl0YWxHYWluc1NlcnZpY2VcIjtcbmltcG9ydCB7IElucHV0LCBMb25nVGVybUJyYWNrZXQsIFJlc3VsdCwgUnVsZXMgfSBmcm9tIFwiLi9kb21haW4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIFVTQUNhcGl0YWxHYWluc1NlcnZpY2VJbXBsIGltcGxlbWVudHMgVVNBQ2FwaXRhbEdhaW5zU2VydmljZSB7XG4gICAgcHJpdmF0ZSBfaW5wdXQ6IElucHV0O1xuICAgIHByaXZhdGUgX3J1bGVzOiBSdWxlcztcblxuICAgIGNvbnN0cnVjdG9yKGlucHV0OiBJbnB1dCwgcnVsZXM6IFJ1bGVzKSB7XG4gICAgICAgIHRoaXMuX2lucHV0ID0gaW5wdXQ7XG4gICAgICAgIHRoaXMuX3J1bGVzID0gcnVsZXM7XG4gICAgfVxuXG4gICAgY2FsY3VsYXRlKCk6IFJlc3VsdCB7XG4gICAgICAgIGNvbnN0IGdhaW4gPSB0aGlzLl9pbnB1dC5jYXBpdGFsR2FpbjtcblxuICAgICAgICBpZiAoZ2FpbiA8PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4geyBjYXBpdGFsR2FpbnNUYXg6IDAsIG5ldEludmVzdG1lbnRJbmNvbWVUYXg6IDAsIHRvdGFsVGF4OiAwLCBlZmZlY3RpdmVSYXRlOiAwLCBicmVha2Rvd25zOiBbXSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNMb25nVGVybSA9IHRoaXMuX2lucHV0LmhvbGRpbmdQZXJpb2RNb250aHMgPiAxMjtcbiAgICAgICAgY29uc3QgYnJhY2tldHMgPSBpc0xvbmdUZXJtID8gdGhpcy5fcnVsZXMubG9uZ1Rlcm1CcmFja2V0cyA6IHRoaXMuX3J1bGVzLnNob3J0VGVybUJyYWNrZXRzO1xuXG4gICAgICAgIGNvbnN0IHsgdGF4LCBicmVha2Rvd25zIH0gPSB0aGlzLmFwcGx5QnJhY2tldHMoZ2FpbiwgdGhpcy5faW5wdXQudG90YWxUYXhhYmxlSW5jb21lLCBicmFja2V0cyk7XG5cbiAgICAgICAgbGV0IG5paXQgPSAwO1xuICAgICAgICBpZiAodGhpcy5faW5wdXQudG90YWxUYXhhYmxlSW5jb21lID4gdGhpcy5fcnVsZXMubmV0SW52ZXN0bWVudEluY29tZVRheC50aHJlc2hvbGQpIHtcbiAgICAgICAgICAgIG5paXQgPSBnYWluICogdGhpcy5fcnVsZXMubmV0SW52ZXN0bWVudEluY29tZVRheC5yYXRlO1xuICAgICAgICAgICAgYnJlYWtkb3ducy5wdXNoKHtcbiAgICAgICAgICAgICAgICBmcm9tOiAnTklJVCcsXG4gICAgICAgICAgICAgICAgdG86ICdBbGwgR2FpbicsXG4gICAgICAgICAgICAgICAgcmF0ZTogdGhpcy5fcnVsZXMubmV0SW52ZXN0bWVudEluY29tZVRheC5yYXRlLFxuICAgICAgICAgICAgICAgIGFtb3VudDogbmlpdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG90YWxUYXggPSB0YXggKyBuaWl0O1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjYXBpdGFsR2FpbnNUYXg6IHRheCxcbiAgICAgICAgICAgIG5ldEludmVzdG1lbnRJbmNvbWVUYXg6IG5paXQsXG4gICAgICAgICAgICB0b3RhbFRheCxcbiAgICAgICAgICAgIGVmZmVjdGl2ZVJhdGU6IGdhaW4gPiAwID8gKHRvdGFsVGF4IC8gZ2FpbikgKiAxMDAgOiAwLFxuICAgICAgICAgICAgYnJlYWtkb3ducyxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFwcGx5QnJhY2tldHMoXG4gICAgICAgIGdhaW46IG51bWJlcixcbiAgICAgICAgdG90YWxJbmNvbWU6IG51bWJlcixcbiAgICAgICAgYnJhY2tldHM6IExvbmdUZXJtQnJhY2tldFtdLFxuICAgICk6IHsgdGF4OiBudW1iZXI7IGJyZWFrZG93bnM6IEJyZWFrZG93bltdIH0ge1xuICAgICAgICBsZXQgdGF4ID0gMDtcbiAgICAgICAgY29uc3QgYnJlYWtkb3duczogQnJlYWtkb3duW10gPSBbXTtcbiAgICAgICAgbGV0IHJlbWFpbmluZyA9IGdhaW47XG4gICAgICAgIGxldCBpbmNvbWVVc2VkID0gdG90YWxJbmNvbWUgLSBnYWluO1xuXG4gICAgICAgIGZvciAoY29uc3QgYnJhY2tldCBvZiBicmFja2V0cykge1xuICAgICAgICAgICAgaWYgKHJlbWFpbmluZyA8PSAwKSBicmVhaztcblxuICAgICAgICAgICAgY29uc3QgdXBwZXIgPSBicmFja2V0LnRvID8/IEluZmluaXR5O1xuXG4gICAgICAgICAgICBpZiAoaW5jb21lVXNlZCA+PSB1cHBlcikgY29udGludWU7XG5cbiAgICAgICAgICAgIGNvbnN0IGJyYWNrZXRTdGFydCA9IE1hdGgubWF4KGJyYWNrZXQuZnJvbSwgaW5jb21lVXNlZCk7XG4gICAgICAgICAgICBjb25zdCBicmFja2V0U3BhY2UgPSB1cHBlciAtIGJyYWNrZXRTdGFydDtcbiAgICAgICAgICAgIGNvbnN0IHRheGFibGUgPSBNYXRoLm1pbihicmFja2V0U3BhY2UsIHJlbWFpbmluZyk7XG5cbiAgICAgICAgICAgIGlmICh0YXhhYmxlID4gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJyYWNrZXRUYXggPSB0YXhhYmxlICogYnJhY2tldC5yYXRlO1xuICAgICAgICAgICAgICAgIHRheCArPSBicmFja2V0VGF4O1xuICAgICAgICAgICAgICAgIHJlbWFpbmluZyAtPSB0YXhhYmxlO1xuICAgICAgICAgICAgICAgIGluY29tZVVzZWQgKz0gdGF4YWJsZTtcblxuICAgICAgICAgICAgICAgIGJyZWFrZG93bnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGZyb206IGAke2JyYWNrZXQuZnJvbX1gLFxuICAgICAgICAgICAgICAgICAgICB0bzogYCR7YnJhY2tldC50byA/PyAnQWJvdmUnfWAsXG4gICAgICAgICAgICAgICAgICAgIHJhdGU6IGJyYWNrZXQucmF0ZSxcbiAgICAgICAgICAgICAgICAgICAgYW1vdW50OiBicmFja2V0VGF4LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHsgdGF4LCBicmVha2Rvd25zIH07XG4gICAgfVxufVxuIl19
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY2FwaXRhbC1nYWlucy91c2EvZG9tYWluL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCcmVha2Rvd24gfSBmcm9tIFwiLi4vLi4vZG9tYWluL3R5cGVzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9uZ1Rlcm1CcmFja2V0IHtcbiAgICBmcm9tOiBudW1iZXI7XG4gICAgdG86IG51bWJlciB8IG51bGw7XG4gICAgcmF0ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJ1bGVzIHtcbiAgICBsb25nVGVybUJyYWNrZXRzOiBMb25nVGVybUJyYWNrZXRbXTtcbiAgICBzaG9ydFRlcm1CcmFja2V0czogTG9uZ1Rlcm1CcmFja2V0W107XG4gICAgbmV0SW52ZXN0bWVudEluY29tZVRheDogeyByYXRlOiBudW1iZXI7IHRocmVzaG9sZDogbnVtYmVyIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5wdXQge1xuICAgIGNhcGl0YWxHYWluOiBudW1iZXI7XG4gICAgdG90YWxUYXhhYmxlSW5jb21lOiBudW1iZXI7XG4gICAgaG9sZGluZ1BlcmlvZE1vbnRoczogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlc3VsdCB7XG4gICAgY2FwaXRhbEdhaW5zVGF4OiBudW1iZXI7XG4gICAgbmV0SW52ZXN0bWVudEluY29tZVRheDogbnVtYmVyO1xuICAgIHRvdGFsVGF4OiBudW1iZXI7XG4gICAgZWZmZWN0aXZlUmF0ZTogbnVtYmVyO1xuICAgIGJyZWFrZG93bnM6IEJyZWFrZG93bltdO1xufVxuIl19
|