Add UnsupportedLine, to formalize a comment convention that exists in fed2019. 1.0.0
authorRobert Sesek <rsesek@bluestatic.org>
Mon, 23 Mar 2020 05:36:29 +0000 (01:36 -0400)
committerRobert Sesek <rsesek@bluestatic.org>
Mon, 23 Mar 2020 05:38:24 +0000 (01:38 -0400)
Also adds sumFormLines() to simplify a common operation.

src/core/Line.ts
src/fed2019/Form1040.ts
src/fed2019/Form1116.ts
src/fed2019/Form8606.ts
src/fed2019/Form8959.ts
src/fed2019/Form8960.ts
src/fed2019/Form8995.ts
src/fed2019/Schedule2.ts
src/fed2019/Schedule3.ts
src/fed2019/ScheduleD.ts

index 300192c0fd00709d906024ef8f86c63d6c23fe94..8995beee8f1545ccf85e5c69ddd957140b5da987 100644 (file)
@@ -122,8 +122,27 @@ export class AccumulatorLine<F extends Form<any>,
   }
 };
 
+export class UnsupportedLine extends Line<number> {
+  constructor(description?: string) {
+    super(description || 'Unsupported');
+  }
+
+  value(tr): number {
+    // Unsupported lines are deliberately omitted from Trace.
+    return 0;
+  }
+};
+
 export function sumLineOfForms<F extends Form<any>, L extends keyof F['lines']>(
     tr: TaxReturn, forms: F[], line: L): number {
   const reducer = (acc: number, curr: F) => acc + curr.getValue(tr, line);
   return forms.reduce(reducer, 0);
 }
+
+export function sumFormLines<F extends Form<any>, L extends keyof F['lines']>(
+    tr: TaxReturn, form: F, lines: L[]): number {
+  let value = 0;
+  for (const line of lines)
+    value += form.getValue(tr, line);
+  return value;
+}
index 584a823de9926c028a7f771f1ca892320254d2ef..4a8b2d0cb9a239c95755e77be3dfdf2aff7a4085 100644 (file)
@@ -4,9 +4,9 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, TaxReturn } from '../core';
-import { Line, AccumulatorLine, ComputedLine, ReferenceLine, sumLineOfForms } from '../core/Line';
+import { Line, AccumulatorLine, ComputedLine, ReferenceLine, UnsupportedLine, sumFormLines, sumLineOfForms } from '../core/Line';
 import { UnsupportedFeatureError } from '../core/Errors';
-import { clampToZero, reduceBySum } from '../core/Math';
+import { clampToZero, reduceBySum, undefinedToZero } from '../core/Math';
 
 import Form8606 from './Form8606';
 import Form8959 from './Form8959';
@@ -54,10 +54,11 @@ export default class Form1040 extends Form<Form1040['lines'], Form1040Input> {
     '4b': new ComputedLine((tr): number => {
       const f8606s = tr.findForms(Form8606);
       return sumLineOfForms(tr, f8606s, '15c') + sumLineOfForms(tr, f8606s, '18');
-    }, 'IRA distributions, taxadble amount'),
-    '4d': new ComputedLine(() => 0),
-    // 4c and 4d are not supported
-    // 5a and 5b are not supported
+    }, 'IRA distributions, taxable amount'),
+    '4c': new UnsupportedLine('Pensions and annuities'),
+    '4d': new UnsupportedLine('Pensions and annuities, taxable amount'),
+    '5a': new UnsupportedLine('Social security benefits'),
+    '5b': new UnsupportedLine('Social security benefits, taxable amount'),
     '6': new ComputedLine((tr): number => {
       const schedD = tr.findForm(ScheduleD);
       if (!schedD)
@@ -71,16 +72,7 @@ export default class Form1040 extends Form<Form1040['lines'], Form1040Input> {
     '7a': new ReferenceLine(Schedule1, '9', 'Other income from Schedule 1', 0),
 
     '7b': new ComputedLine((tr): number => {
-      let income = 0;
-      income += this.getValue(tr, '1');
-      income += this.getValue(tr, '2b');
-      income += this.getValue(tr, '3b');
-      income += this.getValue(tr, '4b');
-      income += this.getValue(tr, '4d');
-      //income += this.getValue(tr, '5b');
-      income += this.getValue(tr, '6');
-      income += this.getValue(tr, '7a');
-      return income;
+      return sumFormLines(tr, this, ['1', '2b', '3b', '4b', '4d', '5b', '6', '7a']);
     }, 'Total income'),
 
     '8a': new ReferenceLine(Schedule1, '22', 'Adjustments to income', 0),
@@ -142,9 +134,15 @@ export default class Form1040 extends Form<Form1040['lines'], Form1040Input> {
       return this.getValue(tr, '12a') + tr.getForm(Schedule2).getValue(tr, '3');
     }, 'Additional tax'),
 
-    // Not supported: 13a - child tax credit
+    '13a': new UnsupportedLine('Child tax credit'),
 
-    '13b': new ReferenceLine(Schedule3, '7', 'Additional credits', 0),
+    '13b': new ComputedLine((tr): number => {
+      let value  = this.getValue(tr, '13a');
+      const sched3 = tr.findForm(Schedule3);
+      if (sched3)
+        value += undefinedToZero(sched3.getValue(tr, '7'));
+      return value;
+    }, 'Additional credits'),
 
     '14': new ComputedLine((tr): number => {
       return clampToZero(this.getValue(tr, '12b') - this.getValue(tr, '13b'));
@@ -174,13 +172,12 @@ export default class Form1040 extends Form<Form1040['lines'], Form1040Input> {
       return reduceBySum(withholding) + additionalMedicare;
     }, 'Federal income tax withheld'),
 
-    // 18a not supported - Earned income credit (EIC)
-    // 18b not supported - Additional child tax credit. Attach Schedule 8812
-    // 18c not supported - American opportunity credit from Form 8863, line 8
+    '18a': new UnsupportedLine('Earned income credit (EIC)'),
+    '18b': new UnsupportedLine('Additional child tax credit. Attach Schedule 8812'),
+    '18c': new UnsupportedLine('American opportunity credit from Form 8863, line 8'),
     '18d': new ReferenceLine(Schedule3, '14', undefined, 0),
     '18e': new ComputedLine((tr): number => {
-      // Should include 18a-18c.
-      return this.getValue(tr, '18d');
+      return sumFormLines(tr, this, ['18a', '18b', '18c', '18d']);
     }),
 
     '19': new ComputedLine((tr): number => {
@@ -260,7 +257,7 @@ export class QDCGTaxWorksheet extends Form<QDCGTaxWorksheet['lines']> {
       return tr.getForm(Form1040).getValue(tr, '6');
     }),
     '4': new ComputedLine((tr): number => this.getValue(tr, '2') + this.getValue(tr, '3')),
-    '5': new ComputedLine(() => 0), // Not supported - Form 4952/4g (nvestment interest expense deduction)
+    '5': new UnsupportedLine('Form 4952@4g (Investment interest expense deduction)'),
     '6': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '4') - this.getValue(tr, '5'))),
     '7': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '1') - this.getValue(tr, '6'))),
     '8': new ComputedLine((tr): number => {
index bbec8fbe57557eccddf2093846fd54ed555b60a9..61cc81bf47101e75afa47ebc395952da46e1b3dc 100644 (file)
@@ -4,7 +4,7 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, Person, TaxReturn } from '../core';
-import { ComputedLine, InputLine, ReferenceLine } from '../core/Line';
+import { ComputedLine, InputLine, ReferenceLine, UnsupportedLine, sumFormLines } from '../core/Line';
 import { UnsupportedFeatureError } from '../core/Errors';
 import { reduceBySum } from '../core/Math';
 
@@ -47,9 +47,9 @@ export default class Form1116 extends Form<Form1116['lines'], Form1116Input> {
     'i': new Input('posessionName'),
     '1a': new Input('grossForeignIncome'),
     // 1b not supported - services as an employee.
-    // 2 not supported - Expenses definitely related to the income
+    '2': new UnsupportedLine('Expenses definitely related to the income'),
     '3a': new ReferenceLine(Form1040, '9', 'Deductions'),
-    '3b': new ComputedLine(() => 0, 'Other deductions'),  // Not supported
+    '3b': new UnsupportedLine('Other deductions'),
     '3c': new ComputedLine((tr): number => {
       return this.getValue(tr, '3a') + this.getValue(tr, '3b');
     }),
@@ -75,28 +75,28 @@ export default class Form1116 extends Form<Form1116['lines'], Form1116Input> {
     '3g': new ComputedLine((tr): number => {
       return this.getValue(tr, '3c') * this.getValue(tr, '3f');
     }),
-    // 4 not supported - Pro rata share of interest expense
+    '4a': new UnsupportedLine('Home mortgage interest'),
+    '4b': new UnsupportedLine('Other interest expense'),
     '5': new Input('lossesFromForeignSources', undefined, 0),
     '6': new ComputedLine((tr): number => {
-      // Should include 2, 4a, 4b.
-      return this.getValue(tr, '3g') + this.getValue(tr, '5');
+      return sumFormLines(tr, this, ['2', '3g', '4a', '4b', '5']);
     }),
     '7': new ComputedLine((tr): number => this.getValue(tr, '1a') - this.getValue(tr, '6')),
     // Skip the complicated Part II matrix and just use the input value.
     '8': new Input('totalForeignTaxesPaidOrAccrued'),
     '9': new ReferenceLine(Form1116 as any, '8'),
-    // 10 not supported - Carryback or carryover
-    '11': new ComputedLine((tr): number => this.getValue(tr, '9') /* + this.getValue(tr, '10') */),
-    // 12 not supported - Reduction in foreign taxes
-    // 13 not supported - Taxes reclassified under high tax kickout
+    '10': new UnsupportedLine('Carryback or carryover'),
+    '11': new ComputedLine((tr): number => this.getValue(tr, '9') + this.getValue(tr, '10')),
+    '12': new UnsupportedLine('Reduction in foreign taxes'),
+    '13': new UnsupportedLine('Taxes reclassified under high tax kickout'),
     '14': new ComputedLine((tr): number => {
-      return this.getValue(tr, '11') /*+
+      return this.getValue(tr, '11') +
              this.getValue(tr, '12') +
-             this.getValue(tr, '13')*/;
+             this.getValue(tr, '13');
     }),
     '15': new ReferenceLine(Form1116 as any, '7'),
-    // 16 not supported - Adjustments to line 15
-    '17': new ComputedLine((tr): number => this.getValue(tr, '15') /* + this.getValue(tr, '16') */),
+    '16': new UnsupportedLine('Adjustments to line 15'),
+    '17': new ComputedLine((tr): number => this.getValue(tr, '15') + this.getValue(tr, '16')),
     // TODO - This does not handle necessary adjustments.
     '18': new ReferenceLine(Form1040, '11b'),
     '19': new ComputedLine((tr): number => this.getValue(tr, '17') / this.getValue(tr, '18')),
@@ -111,7 +111,7 @@ export default class Form1116 extends Form<Form1116['lines'], Form1116Input> {
     '22': new ComputedLine((tr): number => Math.min(this.getValue(tr, '14'), this.getValue(tr, '21'))),
     // 23-30 not supported (other category F1116)
     '31': new ReferenceLine(Form1116 as any, '22'),
-    // 32 not supported - Reduction of credit for international boycott operations
-    '33': new ComputedLine((tr): number => this.getValue(tr, '31') /* - this.getValue(tr, '32')*/),
+    '32': new UnsupportedLine('Reduction of credit for international boycott operations'),
+    '33': new ComputedLine((tr): number => this.getValue(tr, '31') - this.getValue(tr, '32')),
   };
 };
index 38c9fe90dde21bae80e2a56be375e027c10568ff..7d8d4b5e35bf95fb4c03d924b4325f4fe62e4f2b 100644 (file)
@@ -4,7 +4,7 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, Person, TaxReturn } from '../core';
-import { Line, AccumulatorLine, ComputedLine, InputLine, ReferenceLine } from '../core/Line';
+import { Line, AccumulatorLine, ComputedLine, InputLine, ReferenceLine, UnsupportedLine } from '../core/Line';
 import { clampToZero, undefinedToZero } from '../core/Math';
 
 export interface Form8606Input {
@@ -55,8 +55,7 @@ export default class Form8606 extends Form<Form8606['lines'], Form8606Input> {
       return l3 - this.getValue(tr, '13');
     }, 'Total basis in Traditional IRAs'),
     '15a': new ComputedLine((tr): number => this.getValue(tr, '7') - this.getValue(tr, '12')),
-    '15b': new ComputedLine((): number => 0, 'Amount attributable to qualified disaster distributions'),
-    // 15b not supported - amount on line 15a attributable
+    '15b': new UnsupportedLine('Amount attributable to qualified disaster distributions'),
     '15c': new ComputedLine((tr): number => this.getValue(tr, '15a') - this.getValue(tr, '15b'), 'Taxable amount'),
 
     // Part 2
index 844261f7f4c4364e3845052180cfa5d1061f7c71..a4ebc9f9bec9c6780ccb860cbd25275a6af5051f 100644 (file)
@@ -4,7 +4,7 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, TaxReturn } from '../core';
-import { Line, AccumulatorLine, ComputedLine, ReferenceLine } from '../core/Line';
+import { Line, AccumulatorLine, ComputedLine, ReferenceLine, UnsupportedLine, sumFormLines } from '../core/Line';
 import { clampToZero } from '../core/Math';
 
 import Form1040, { FilingStatus } from './Form1040';
@@ -15,11 +15,10 @@ export default class Form8959 extends Form<Form8959['lines']> {
 
   readonly lines = {
     '1': new AccumulatorLine(W2, '5', 'Medicare wages'),
-    // 2 is not supported (Unreported tips from Form 4137)
-    // 3 is not supported (Wages from Form 8919)
+    '2': new UnsupportedLine('Unreported tips from Form 4137'),
+    '3': new UnsupportedLine('Wages from Form 8919'),
     '4': new ComputedLine((tr): number => {
-      // Should include 2-3.
-      return this.getValue(tr, '1');
+      return sumFormLines(tr, this, ['1', '2', '3']);
     }),
     '5': new ComputedLine((tr): number => {
       return Form8959.filingStatusLimit(tr.getForm(Form1040).filingStatus);
@@ -46,10 +45,9 @@ export default class Form8959 extends Form<Form8959['lines']> {
     '22': new ComputedLine((tr): number => {
       return clampToZero(this.getValue(tr, '19') - this.getValue(tr, '21'));
     }, 'Additional Medicare withholding on Medicare wages'),
-    // 23 is not supported (Additional Medicare Tax withholding on railroad retirement (RRTA) compensation)
+    '23': new UnsupportedLine('Additional Medicare Tax withholding on railroad retirement (RRTA) compensation'),
     '24': new ComputedLine((tr): number => {
-      // Should include 23.
-      return this.getValue(tr, '22');
+      return this.getValue(tr, '22') + this.getValue(tr, '23');
     }),
   };
 
index a871e82c7b300a08bad7b70c9336f0056b2f080d..724303ec7ebc9c4b020df0d1eef0caf36ba75969 100644 (file)
@@ -4,7 +4,7 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, TaxReturn } from '../core';
-import { ComputedLine, ReferenceLine } from '../core/Line';
+import { ComputedLine, ReferenceLine, UnsupportedLine, sumFormLines } from '../core/Line';
 import { clampToZero, undefinedToZero } from '../core/Math';
 
 import Form1040, { FilingStatus } from './Form1040';
@@ -18,30 +18,23 @@ export default class Form8960 extends Form<Form8960['lines']> {
     // Section 6013 elections not supported.
     '1': new ReferenceLine(Form1040, '2b', 'Taxable interest'),
     '2': new ReferenceLine(Form1040, '3b', 'Ordinary dividends'),
-    // 3 not supported - Annuities
-    // 4a not supported - Rental real estate, royalties, partnerships, S corporations, trusts, etc
-    // 4b not supported - Adjustment for net income or loss derived in the ordinary course of a nonsection 1411 trade or business
-    // 4c not supported - 4a+4b
+    '3': new UnsupportedLine('Annuities'),
+    '4a': new UnsupportedLine('Rental real estate, royalties, partnerships, S corporations, trusts, etc'),
+    '4b': new UnsupportedLine('Adjustment for net income or loss derived in the ordinary course of a nonsection 1411 trade or business'),
+    '4c': new ComputedLine((tr): number => this.getValue(tr, '4a') + this.getValue(tr, '4b')),
     '5a': new ComputedLine((tr): number => {
       return (new ReferenceLine(Form1040, '6')).value(tr) +
              undefinedToZero(new ReferenceLine(Schedule1, '4', undefined, 0).value(tr));
     }, 'Net gain or loss'),
-    // 5b not supported - Net gain or loss from disposition of property that is not subject to net investment income tax
-    // 5c not supported - Adjustment from disposition of partnership interest or S corporation stock
+    '5b': new UnsupportedLine('Net gain or loss from disposition of property that is not subject to net investment income tax'),
+    '5c': new UnsupportedLine('Adjustment from disposition of partnership interest or S corporation stock'),
     '5d': new ComputedLine((tr): number => {
-      // Should include 5b-5c.
-      return this.getValue(tr, '5a');
+      return sumFormLines(tr, this, ['5a', '5b', '5c']);
     }),
-    // 6 not supported - Adjustments to investment income for certain CFCs and PFICs
-    // 7 not supported - Other modifications to investment income
+    '6': new UnsupportedLine('Adjustments to investment income for certain CFCs and PFICs'),
+    '7': new UnsupportedLine('Other modifications to investment income'),
     '8': new ComputedLine((tr): number => {
-      return this.getValue(tr, '1') +
-             this.getValue(tr, '2') +
-             /*this.getValue(tr, '3') +
-             this.getValue(tr, '4c') +*/
-             this.getValue(tr, '5d') /*+
-             this.getValue(tr, '6') +
-             this.getValue(tr, '7')*/;
+      return sumFormLines(tr, this, ['1', '2', '3', '4c', '5d', '6', '7']);
     }),
 
     // Part 2
index 677f9e265424b0dc2f928df8a68bd7c0f6df15d7..52bcbb9420293e2a20fae50eabca00187dd7c149 100644 (file)
@@ -4,7 +4,7 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, Person, TaxReturn } from '../core';
-import { AccumulatorLine, ComputedLine, InputLine } from '../core/Line';
+import { AccumulatorLine, ComputedLine, InputLine, UnsupportedLine } from '../core/Line';
 import { clampToZero } from '../core/Math';
 
 import Form1040 from './Form1040';
@@ -24,7 +24,7 @@ export default class Form8995REIT extends Form<Form8995REIT['lines']> {
   // This uses line numbers from 8995-A.
   readonly lines = {
     // 1-26 not supported
-    '27': new ComputedLine(() => 0, 'Total qualified business income component'), // Not supported.
+    '27': new UnsupportedLine('Total qualified business income component'),
     '28': new AccumulatorLine(Form1099DIV, '5', 'Qualified REIT dividends'),
     '29': new InputLine<Form8995REITInput>('qualifiedReitDividendCarryforward', undefined, 0),
     '30': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '28') + this.getValue(tr, '29'))),
@@ -53,7 +53,7 @@ export default class Form8995REIT extends Form<Form8995REIT['lines']> {
     '35': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '33') - this.getValue(tr, '34'))),
     '36': new ComputedLine((tr): number => this.getValue(tr, '35') * 0.20, 'Income limitation'),
     '37': new ComputedLine((tr): number => Math.min(this.getValue(tr, '32'), this.getValue(tr, '36'))),
-    '38': new ComputedLine(() => 0, 'DPAD under section 199A(g) allocated from an agricultural or horticultural cooperative'),  // Not supported,
+    '38': new UnsupportedLine('DPAD under section 199A(g) allocated from an agricultural or horticultural cooperative'),
     '39': new ComputedLine((tr): number => this.getValue(tr, '37') + this.getValue(tr, '38')),
     '40': new ComputedLine((tr): number => Math.min(0, this.getValue(tr, '28') + this.getValue(tr, '29')), 'Total qualified REIT dividends and PTP loss carryforward.'),
   };
index eb9899c4ad2397a7cbc61003c3aeb2261c354b77..b2a2d51057542b499fe6f62559c59b3f4b9f18e1 100644 (file)
@@ -4,7 +4,7 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, TaxReturn } from '../core';
-import { ComputedLine } from '../core/Line';
+import { ComputedLine, UnsupportedLine, sumFormLines } from '../core/Line';
 import { UnsupportedFeatureError } from '../core/Errors';
 
 import Form1040, { FilingStatus } from './Form1040';
@@ -35,16 +35,15 @@ export default class Schedule2 extends Form<Schedule2['lines']> {
       }
       throw new UnsupportedFeatureError('The AMT is not supported');
     }, 'AMT'),
-    '2': new ComputedLine(() => 0, 'Excess advance premium tax credit repayment'),  // Not supported.
+    '2': new UnsupportedLine('Excess advance premium tax credit repayment'),
     '3': new ComputedLine((tr): number => {
-      // Should include line 2.
-      return this.getValue(tr, '1');
+      return this.getValue(tr, '1') + this.getValue(tr, '2');
     }),
 
-    // 4 is not supported (Self-employment tax.)
-    // 5 is not supported (Unreported social security and Medicare tax from)
-    // 6 is not supported (Additional tax on IRAs, other qualified retirement plans, and other tax-favored accounts)
-    // 7 is not supported (Household employment taxes.)
+    '4': new UnsupportedLine('Self-employment tax.'),
+    '5': new UnsupportedLine('Unreported social security and Medicare tax from'),
+    '6': new UnsupportedLine('Additional tax on IRAs, other qualified retirement plans, and other tax-favored accounts'),
+    '7': new UnsupportedLine('Household employment taxes.'),
     '8': new ComputedLine((tr): number => {
       const f1040 = tr.getForm(Form1040);
       const wages = f1040.getLine('1').value(tr);
@@ -65,11 +64,10 @@ export default class Schedule2 extends Form<Schedule2['lines']> {
 
       return value;
     }),
-    // 9 is not supported (Section 965 net tax liability installment from Form 965-A)
+    '9': new UnsupportedLine('Section 965 net tax liability installment from Form 965-A'),
 
     '10': new ComputedLine((tr): number => {
-      // Should be lines 4 - 8.
-      return this.getValue(tr, '8');
+      return sumFormLines(tr, this, ['4', '5', '6', '7', '8']);
     })
   };
 };
index 98da58ccb74c44d604a0e7a30d62186a2e41bd79..055728868f10ec27a703118271902edaeab63faa 100644 (file)
@@ -4,7 +4,7 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, TaxReturn } from '../core';
-import { AccumulatorLine, ComputedLine, InputLine, ReferenceLine } from '../core/Line';
+import { AccumulatorLine, ComputedLine, InputLine, ReferenceLine, UnsupportedLine, sumFormLines } from '../core/Line';
 import { NotFoundError, UnsupportedFeatureError } from '../core/Errors';
 
 import Form1040, { FilingStatus } from './Form1040';
@@ -35,31 +35,29 @@ export default class Schedule3 extends Form<Schedule3['lines'], Schedule3Input>
       }
       return tr.getForm(Form1116).getValue(tr, '33');
     }, 'Foreign tax credit'),
-    // 2 not supported - Credit for child and dependent care expenses. Attach Form 2441
-    // 3 not supported - Education credits from Form 8863, line 19
-    // 4 not supported - Retirement savings contributions credit. Attach Form 8880
-    // 5 not supported - Residential energy credits. Attach Form 5695
-    // 6a not supported - Form 3800
-    // 6b not supported - Form 8801
-    // 6c not supported - Other nonrefundable credits
+    '2': new UnsupportedLine('Credit for child and dependent care expenses. Attach Form 2441'),
+    '3': new UnsupportedLine('Education credits from Form 8863, line 19'),
+    '4': new UnsupportedLine('Retirement savings contributions credit. Attach Form 8880'),
+    '5': new UnsupportedLine('Residential energy credits. Attach Form 5695'),
+    '6a': new UnsupportedLine('Form 3800'),
+    '6b': new UnsupportedLine('Form 8801'),
+    '6c': new UnsupportedLine('Other nonrefundable credits'),
     '7': new ComputedLine((tr): number => {
-      // Should include 2-6.
-      return this.getValue(tr, '1');
+      return sumFormLines(tr, this, ['1', '2', '3', '4', '5', '6a', '6b', '6c']);
     }),
 
     // Part 2
     '8': new InputLine<Schedule3Input>('estimatedTaxPayments'),
-    // 9 not supported - Net premium tax credit. Attach Form 8962
-    // 10 not supported - Amount paid with request for extension to file (see instructions)
-    // 11 not supported - Excess social security and tier 1 RRTA tax withheld
-    // 12 not supported - Credit for federal tax on fuels. Attach Form 4136
-    // 13a not supported - Form 2439
+    '9': new UnsupportedLine('Net premium tax credit. Attach Form 8962'),
+    '10': new UnsupportedLine('Amount paid with request for extension to file (see instructions)'),
+    '11': new UnsupportedLine('Excess social security and tier 1 RRTA tax withheld'),
+    '12': new UnsupportedLine('Credit for federal tax on fuels. Attach Form 4136'),
+    '13a': new UnsupportedLine('Form 2439'),
     // 13b is reserved
-    // 13c not supported - Form 8885
-    // 13d not supported - Other refundable credits
+    '13c': new UnsupportedLine('Form 8885'),
+    '13d': new UnsupportedLine('Other refundable credits'),
     '14': new ComputedLine((tr): number => {
-      // Should include 9-13.
-      return this.getValue(tr, '8');
+      return sumFormLines(tr, this, ['8', '9', '10', '11', '12', '13a', '13c', '13d']);
     }),
   };
 };
index 08264c11a5e40fd941755eb1405e248d3462633e..0925dc9e97fa5817ed9f4218389d0135589eddf1 100644 (file)
@@ -4,7 +4,7 @@
 // SPDX-License-Identifier: GPL-3.0-only
 
 import { Form, Person, TaxReturn } from '../core';
-import { Line, AccumulatorLine, ComputedLine, ReferenceLine, sumLineOfForms } from '../core/Line';
+import { Line, AccumulatorLine, ComputedLine, ReferenceLine, UnsupportedLine, sumFormLines, sumLineOfForms } from '../core/Line';
 import { clampToZero } from '../core/Math';
 import { NotFoundError, UnsupportedFeatureError } from '../core/Errors';
 
@@ -17,35 +17,34 @@ export default class ScheduleD extends Form<ScheduleD['lines']> {
 
   readonly lines = {
     // 1a not supported (Totals for all short-term transactions reported on Form 1099-B for which basis was reported to the IRS and for which you have no adjustments)
-    // 4 is not supported (Short-term gain from Form 6252 and short-term gain or (loss) from Forms 4684, 6781, and 8824)
-    // 5 is not supported (Net short-term gain or (loss) from partnerships, S corporations, estates, and trusts from Schedule(s) K-1)
-    // 6 is not supported (Short-term capital loss carryover. Enter the amount, if any, from line 8 of your Capital Loss Carryover Worksheet in the instructions)
+    '4': new UnsupportedLine(),  // Short-term gain from Form 6252 and short-term gain or (loss) from Forms 4684, 6781, and 8824
+    '5': new UnsupportedLine(),  // Net short-term gain or (loss) from partnerships, S corporations, estates, and trusts from Schedule(s) K-1
+    '6': new UnsupportedLine(),  // Short-term capital loss carryover. Enter the amount, if any, from line 8 of your Capital Loss Carryover Worksheet in the instructions
 
     '7': new ComputedLine((tr): number => {
       // 1-3 are computed by Form8949.
-      // 4-6 should be included.
+      let value = sumFormLines(tr, this, ['4', '5', '6']);
       const f8949 = tr.getForm(Form8949);
-      return f8949.getValue(tr, 'boxA').gainOrLoss +
-             f8949.getValue(tr, 'boxB').gainOrLoss +
-             f8949.getValue(tr, 'boxC').gainOrLoss;
+      value += f8949.getValue(tr, 'boxA').gainOrLoss;
+      value += f8949.getValue(tr, 'boxB').gainOrLoss;
+      value += f8949.getValue(tr, 'boxC').gainOrLoss;
+      return value;
     }, 'Net short-term capital gain or loss'),
 
     // 8a is not supported.
 
-    // 11 is not supported (Gain from Form 4797, Part I; long-term gain from Forms 2439 and 6252; and long-term gain or (loss) from Forms 4684, 6781, and 8824)
-    // 12 is not supported (Net long-term gain or (loss) from partnerships, S corporations, estates, and trusts from Schedule(s) K-1)
-
+    '11': new UnsupportedLine(),  // Gain from Form 4797, Part I; long-term gain from Forms 2439 and 6252; and long-term gain or (loss) from Forms 4684, 6781, and 8824
+    '12': new UnsupportedLine(),  // Net long-term gain or (loss) from partnerships, S corporations, estates, and trusts from Schedule(s) K-1
     '13': new AccumulatorLine(Form1099DIV, '2a', 'Capital gain distributions'),
-
-    // 14 is not supported (Long-term capital loss carryover. Enter the amount, if any, from line 13 of your Capital Loss Carryover Worksheet in the instructions)
+    '14': new UnsupportedLine('Long-term capital loss carryover'),
 
     '15': new ComputedLine((tr): number => {
-      // 11-14 should be included.
+      let value = sumFormLines(tr, this, ['11', '12', '13', '14']);
       const f8949 = tr.getForm(Form8949);
-      return f8949.getValue(tr, 'boxD').gainOrLoss +
-             f8949.getValue(tr, 'boxE').gainOrLoss +
-             f8949.getValue(tr, 'boxF').gainOrLoss +
-             this.getValue(tr, '13');
+      value += f8949.getValue(tr, 'boxD').gainOrLoss;
+      value += f8949.getValue(tr, 'boxE').gainOrLoss;
+      value += f8949.getValue(tr, 'boxF').gainOrLoss;
+      return value;
     }, 'Net long-term capital gain or loss'),
 
     '16': new ComputedLine((tr): number => {
@@ -61,12 +60,9 @@ export default class ScheduleD extends Form<ScheduleD['lines']> {
       // If no, goto 22.
     }, 'Both ST and LT are gains'),
 
-    '18': new ComputedLine((tr): number | undefined => {
-      // Not supported - only for gains on Qualified Small Business Stock or collectibles.
-      return 0;
-    }, '28% Rate Gain Worksheet Value'),
+    '18': new UnsupportedLine('28% Rate Gain Worksheet Value (Qualified Small Business Stock or collectibles.)'),
 
-    '19': new ComputedLine(() => undefined, 'Unrecaptured Section 1250 Gain Worksheet'), // Not supported.
+    '19': new UnsupportedLine('Unrecaptured Section 1250 Gain Worksheet'),
 
     '20': new ComputedLine((tr): boolean | undefined => {
       const l18 = this.getValue(tr, '18');
@@ -95,8 +91,8 @@ export class ScheduleDTaxWorksheet extends Form<ScheduleDTaxWorksheet['lines']>
   readonly lines = {
     '1': new ReferenceLine(Form1040, '11b'),
     '2': new ReferenceLine(Form1040, '3a'),
-    // TODO 3 - form 4952
-    // TODO 4 - 4952
+    '3': new UnsupportedLine('Form 4952@4g'),
+    '4': new UnsupportedLine('Form 4952@4e'),
     '5': new ComputedLine((tr): number => 0),
     '6': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '2') - this.getValue(tr, '5'))),
     '7': new ComputedLine((tr): number => {
@@ -104,8 +100,7 @@ export class ScheduleDTaxWorksheet extends Form<ScheduleDTaxWorksheet['lines']>
       return Math.min(schedD.getValue(tr, '15'), schedD.getValue(tr, '16'));
     }),
     '8': new ComputedLine((tr): number => {
-      return 0;
-      // return Math.min(this.getValue(tr, '3'), this.getValue(tr, '4'));
+      return Math.min(this.getValue(tr, '3'), this.getValue(tr, '4'));
     }),
     '9': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '7') - this.getValue(tr, '8'))),
     '10': new ComputedLine((tr): number => this.getValue(tr, '6') + this.getValue(tr, '9')),
@@ -167,8 +162,7 @@ export class ScheduleDTaxWorksheet extends Form<ScheduleDTaxWorksheet['lines']>
     '34': new ComputedLine((tr): number => this.getValue(tr, '33') * 0.20),
     '35': new ComputedLine((tr): number => {
       const schedD = tr.getForm(ScheduleD);
-      // TODO - line 19 is not supported.
-      return Math.min(this.getValue(tr, '9'), Infinity); //schedD.getValue(tr, '19'));
+      return Math.min(this.getValue(tr, '9'), schedD.getValue(tr, '19'));
     }),
     '36': new ComputedLine((tr): number => this.getValue(tr, '10') + this.getValue(tr, '21')),
     '37': new ReferenceLine(ScheduleDTaxWorksheet as any, '1'),
@@ -196,11 +190,7 @@ export class ScheduleDTaxWorksheet extends Form<ScheduleDTaxWorksheet['lines']>
       return computeTax(income, tr.getForm(Form1040).filingStatus);
     }),
     '45': new ComputedLine((tr): number => {
-      return this.getValue(tr, '31') +
-             this.getValue(tr, '34') +
-             this.getValue(tr, '40') +
-             this.getValue(tr, '43') +
-             this.getValue(tr, '44');
+      return sumFormLines(tr, this, ['31', '34', '40', '43', '44']);
     }),
     '46': new ComputedLine((tr): number => {
       const income = this.getValue(tr, '1');