Move some computations for Form1040 into methods.
[ustaxlib.git] / src / fed2019 / Form8960.ts
1 // Copyright 2020 Blue Static <https://www.bluestatic.org>
2 // This program is free software licensed under the GNU General Public License,
3 // version 3.0. The full text of the license can be found in LICENSE.txt.
4 // SPDX-License-Identifier: GPL-3.0-only
5
6 import { Form, TaxReturn } from '../core';
7 import { Line, ComputedLine, ReferenceLine, SymbolicLine, UnsupportedLine, sumFormLines } from '../core/Line';
8 import { clampToZero, undefinedToZero } from '../core/Math';
9
10 import { Constants } from './TaxReturn';
11 import Form1040, { FilingStatus } from './Form1040';
12 import Schedule1 from './Schedule1';
13
14 export default class Form8960 extends Form {
15 readonly name = '8960';
16
17 readonly lines = {
18 // Part 1
19 // Section 6013 elections not supported.
20 '1': new SymbolicLine(Form1040, 'taxableInterest', 'Taxable interest'),
21 '2': new ReferenceLine(Form1040, '3b', 'Ordinary dividends'),
22 '3': new UnsupportedLine('Annuities'),
23 '4a': new UnsupportedLine('Rental real estate, royalties, partnerships, S corporations, trusts, etc'),
24 '4b': new UnsupportedLine('Adjustment for net income or loss derived in the ordinary course of a nonsection 1411 trade or business'),
25 '4c': new ComputedLine((tr): number => this.getValue(tr, '4a') + this.getValue(tr, '4b')),
26 '5a': new ComputedLine((tr): number => {
27 return (new SymbolicLine(Form1040, 'capitalGainOrLoss')).value(tr) +
28 undefinedToZero(new ReferenceLine(Schedule1, '4', undefined, 0).value(tr));
29 }, 'Net gain or loss'),
30 '5b': new UnsupportedLine('Net gain or loss from disposition of property that is not subject to net investment income tax'),
31 '5c': new UnsupportedLine('Adjustment from disposition of partnership interest or S corporation stock'),
32 '5d': new ComputedLine((tr): number => {
33 return sumFormLines(tr, this, ['5a', '5b', '5c']);
34 }),
35 '6': new UnsupportedLine('Adjustments to investment income for certain CFCs and PFICs'),
36 '7': new UnsupportedLine('Other modifications to investment income'),
37 '8': new ComputedLine((tr): number => {
38 return sumFormLines(tr, this, ['1', '2', '3', '4c', '5d', '6', '7']);
39 }),
40
41 // Part 2
42 // 9a not supported - Investment interest expenses
43 // 9b not supported - State, local, and foreign income tax
44 // 9c not supported - Miscellaneous investment expenses
45 // 9d not supported - 9a+9b+9c
46 // 10 not supported - Additional modifications
47 '11': new ComputedLine(() => 0, 'Total deductions and modifications'), // Not supported - 9d+10.
48
49 // Part 3
50 '12': new ComputedLine((tr): number => this.getValue(tr, '8') - this.getValue(tr, '11'), 'Net investment income'),
51 '13': new SymbolicLine(Form1040, 'adjustedGrossIncome', 'Modified adjusted gross income'),
52 '14': new ComputedLine((tr): number => {
53 return Form8960.filingStatusLimit(tr);
54 }, 'Threshold'),
55 '15': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '13') - this.getValue(tr, '14'))),
56 '16': new ComputedLine((tr): number => Math.min(this.getValue(tr, '12'), this.getValue(tr, '15'))),
57 '17': new ComputedLine((tr): number => this.getValue(tr, '16') * tr.constants.niit.rate, 'Net investment income tax'),
58
59 // 18 - 21 not supported (Estates and Trusts)
60 };
61
62 static filingStatusLimit(tr: TaxReturn): number {
63 const filingStatus = tr.getForm(Form1040).filingStatus;
64 return tr.constants.niit.limit[filingStatus];
65 }
66 };