Add UnsupportedLine, to formalize a comment convention that exists in fed2019.
[ustaxlib.git] / src / fed2019 / Form8995.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, Person, TaxReturn } from '../core';
7 import { AccumulatorLine, ComputedLine, InputLine, UnsupportedLine } from '../core/Line';
8 import { clampToZero } from '../core/Math';
9
10 import Form1040 from './Form1040';
11 import Form1099DIV from './Form1099DIV';
12 import ScheduleD from './ScheduleD';
13
14 export interface Form8995REITInput {
15 qualifiedReitDividendCarryforward?: number;
16 };
17
18 // Dividends from REITs get preferential tax treatment, but the form used to
19 // calculate that differs based off taxable income amounts. But the QBI
20 // computation for RETIs is the same. This just models the REIT portion.
21 export default class Form8995REIT extends Form<Form8995REIT['lines']> {
22 readonly name = '8995 REIT';
23
24 // This uses line numbers from 8995-A.
25 readonly lines = {
26 // 1-26 not supported
27 '27': new UnsupportedLine('Total qualified business income component'),
28 '28': new AccumulatorLine(Form1099DIV, '5', 'Qualified REIT dividends'),
29 '29': new InputLine<Form8995REITInput>('qualifiedReitDividendCarryforward', undefined, 0),
30 '30': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '28') + this.getValue(tr, '29'))),
31 '31': new ComputedLine((tr): number => this.getValue(tr, '30') * 0.20, 'REIT and PTP component'),
32 '32': new ComputedLine((tr): number => this.getValue(tr, '27') + this.getValue(tr, '31'), 'QBI deduction before limitation'),
33 '33': new ComputedLine((tr): number => {
34 const f1040 = tr.getForm(Form1040);
35 return f1040.getValue(tr, '8b') - f1040.getValue(tr, '9');
36 }, 'Taxable income before deduction'),
37 '34': new ComputedLine((tr): number => {
38 const f1040 = tr.getForm(Form1040);
39
40 let value = f1040.getValue(tr, '3a');
41
42 const schedD = tr.findForm(ScheduleD);
43 if (schedD) {
44 value += Math.min(
45 clampToZero(schedD.getValue(tr, '15')),
46 clampToZero(schedD.getValue(tr, '16')));
47 } else {
48 value += f1040.getValue(tr, '6');
49 }
50
51 return value;
52 }, 'Net capital gain'),
53 '35': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '33') - this.getValue(tr, '34'))),
54 '36': new ComputedLine((tr): number => this.getValue(tr, '35') * 0.20, 'Income limitation'),
55 '37': new ComputedLine((tr): number => Math.min(this.getValue(tr, '32'), this.getValue(tr, '36'))),
56 '38': new UnsupportedLine('DPAD under section 199A(g) allocated from an agricultural or horticultural cooperative'),
57 '39': new ComputedLine((tr): number => this.getValue(tr, '37') + this.getValue(tr, '38')),
58 '40': new ComputedLine((tr): number => Math.min(0, this.getValue(tr, '28') + this.getValue(tr, '29')), 'Total qualified REIT dividends and PTP loss carryforward.'),
59 };
60 };