From 577b2465f3ce66dc7ecd2ea36e6fea26936f63b8 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Sun, 8 Mar 2020 12:07:50 -0400 Subject: [PATCH] Add Schedule 3. --- src/fed2019/Form1040.ts | 19 ++++++---- src/fed2019/Schedule3.test.ts | 66 +++++++++++++++++++++++++++++++++++ src/fed2019/Schedule3.ts | 61 ++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 6 deletions(-) create mode 100644 src/fed2019/Schedule3.test.ts create mode 100644 src/fed2019/Schedule3.ts diff --git a/src/fed2019/Form1040.ts b/src/fed2019/Form1040.ts index c9c6526..13de9cd 100644 --- a/src/fed2019/Form1040.ts +++ b/src/fed2019/Form1040.ts @@ -12,6 +12,7 @@ import Form1099R, { Box7Code } from './Form1099R'; import FormW2 from './FormW2'; import Schedule1 from './Schedule1'; import Schedule2 from './Schedule2'; +import Schedule3 from './Schedule3'; import ScheduleD, { ScheduleDTaxWorksheet } from './ScheduleD'; export enum FilingStatus { @@ -127,10 +128,7 @@ export default class Form1040 extends Form { // Not supported: 13a - child tax credit - '13b': new ComputedLine((tr): number => { - // TODO: add Sched 3.L7 - return 0; - }, 'Additional credits'), + '13b': new ReferenceLine(Schedule3, '7', 'Additional credits', 0), '14': new ComputedLine((tr): number => { const l12b = this.getValue(tr, '12b'); @@ -163,9 +161,18 @@ export default class Form1040 extends Form { return reduceBySum(withholding) + additionalMedicare; }, 'Federal income tax withheld'), - // 18 not supported + // 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 + '18d': new ReferenceLine(Schedule3, '14', undefined, 0), + '18e': new ComputedLine((tr): number => { + // Should include 18a-18c. + return this.getValue(tr, '18d'); + }), - '19': new ReferenceLine(Form1040 as any, '17', 'Total payments'), + '19': new ComputedLine((tr): number => { + return this.getValue(tr, '17') + this.getValue(tr, '18e'); + }, 'Total payments'), '20': new ComputedLine((tr): number => { const l16: number = this.getValue(tr, '16'); diff --git a/src/fed2019/Schedule3.test.ts b/src/fed2019/Schedule3.test.ts new file mode 100644 index 0000000..a22507c --- /dev/null +++ b/src/fed2019/Schedule3.test.ts @@ -0,0 +1,66 @@ +import TaxReturn from '../TaxReturn'; +import Person from '../Person'; +import { NotFoundError } from '../Errors'; + +import Form1040, { FilingStatus } from './Form1040'; +import Form1099DIV from './Form1099DIV'; +import Form1116 from './Form1116'; +import Form8949 from './Form8949'; +import Schedule3 from './Schedule3'; +import ScheduleD from './ScheduleD'; + +test('foreign tax credit, form 1116 not required', () => { + const filingStatusToForeignTax = { + [FilingStatus.Single]: 200, + [FilingStatus.MarriedFilingJoint]: 500, + [FilingStatus.MarriedFilingSeparate]: 200 + }; + + for (const filingStatus of Object.values(FilingStatus)) { + const p = Person.self('A'); + const tr = new TaxReturn(2019); + tr.addForm(new Form1040({ filingStatus })); + tr.addForm(new Form8949); + tr.addForm(new ScheduleD); + tr.addForm(new Form1099DIV({ + payer: 'Brokerage', + payee: p, + ordinaryDividends: 200000, + qualifiedDividends: 70000, + totalCapitalGain: 300, + foreignTaxPaid: filingStatusToForeignTax[filingStatus], + })); + const f = new Schedule3(); + tr.addForm(f); + + expect(f.getValue(tr, '1')).toBe(filingStatusToForeignTax[filingStatus]); + } +}); + +test('foreign tax credit, form 1116 required', () => { + const filingStatusToForeignTax = { + [FilingStatus.Single]: 400, + [FilingStatus.MarriedFilingJoint]: 600, + [FilingStatus.MarriedFilingSeparate]: 400 + }; + + for (const filingStatus of Object.values(FilingStatus)) { + const p = Person.self('A'); + const tr = new TaxReturn(2019); + tr.addForm(new Form1040({ filingStatus })); + tr.addForm(new Form8949); + tr.addForm(new ScheduleD); + tr.addForm(new Form1099DIV({ + payer: 'Brokerage', + payee: p, + ordinaryDividends: 200000, + qualifiedDividends: 70000, + totalCapitalGain: 300, + foreignTaxPaid: filingStatusToForeignTax[filingStatus], + })); + const f = new Schedule3(); + tr.addForm(f); + + expect(() => f.getValue(tr, '1')).toThrow(NotFoundError); + } +}); diff --git a/src/fed2019/Schedule3.ts b/src/fed2019/Schedule3.ts new file mode 100644 index 0000000..c9fed01 --- /dev/null +++ b/src/fed2019/Schedule3.ts @@ -0,0 +1,61 @@ +import Form from '../Form'; +import TaxReturn from '../TaxReturn'; +import { AccumulatorLine, ComputedLine, InputLine, ReferenceLine } from '../Line'; +import { NotFoundError, UnsupportedFeatureError } from '../Errors'; + +import Form1040, { FilingStatus } from './Form1040'; +import Form1099DIV from './Form1099DIV'; +import Form1099INT from './Form1099INT'; +import Form1116 from './Form1116'; +import Schedule2 from './Schedule2'; + +export interface Schedule3Input { + estimatedTaxPayments?: number; +}; + +export default class Schedule3 extends Form { + readonly name = 'Schedule 3'; + + readonly _lines = { + // Part 1 + '1': new ComputedLine((tr): number => { + const f1040 = tr.getForm(Form1040); + + const totalForeignTax = (new AccumulatorLine(Form1099DIV, '7')).value(tr) + + (new AccumulatorLine(Form1099INT, '6')).value(tr); + const limit = f1040.getInput('filingStatus') == FilingStatus.MarriedFilingJoint ? 600 : 300; + + if (totalForeignTax < limit) { + const sched2l2 = new ReferenceLine(Schedule2, '2', undefined, 0); + return Math.min(totalForeignTax, f1040.getValue(tr, '12a') + sched2l2.value(tr)); + } + 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 + '7': new ComputedLine((tr): number => { + // Should include 2-6. + return this.getValue(tr, '1'); + }), + + // Part 2 + '8': new InputLine('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 + // 13b is reserved + // 13c not supported - Form 8885 + // 13d not supported - Other refundable credits + '14': new ComputedLine((tr): number => { + // Should include 9-13. + return this.getValue(tr, '8'); + }), + }; +}; -- 2.22.5