test('add and get line', () => {
const l = new ComputedLine<number>(() => 42);
- class TestForm extends Form<TestForm['_lines']> {
+ class TestForm extends Form<TestForm['lines']> {
readonly name = 'Test Form';
- protected readonly _lines = { '1': l };
+ readonly lines = { '1': l };
};
const f = new TestForm();
});
test('get non-existent line', () => {
- class TestForm extends Form<TestForm['_lines']> {
+ class TestForm extends Form<TestForm['lines']> {
readonly name = 'Test';
- protected readonly _lines = {};
+ readonly lines = {};
};
const f = new TestForm();
class TestForm extends Form<any, TestInput> {
readonly name = '1040';
- protected readonly _lines = null;
+ readonly lines = null;
};
const f = new TestForm({ filingStatus: 'S', money: 100.0 });
});
test('get value', () => {
- class TestForm extends Form<TestForm['_lines']> {
+ class TestForm extends Form<TestForm['lines']> {
readonly name = 'Form';
- protected readonly _lines = {
+ readonly lines = {
line: new ComputedLine<number>(() => 42),
};
};
test('form types', () => {
class FormA extends Form<any> {
readonly name = 'A';
- protected readonly _lines = {};
+ readonly lines = {};
};
class FormB extends Form<any> {
readonly name = 'B';
- protected readonly _lines = {};
+ readonly lines = {};
};
expect(isFormT(new FormA(), FormA)).toBe(true);
I = unknown> {
abstract readonly name: string;
- protected abstract readonly _lines: L;
+ abstract readonly lines: L;
readonly supportsMultipleCopies: boolean = false;
private readonly _input?: I;
- // Avoid using this; prefer the getLine() helpers declared below. This
- // is only exposed for propagating line type information.
- get lines(): L { return this._lines; }
-
constructor(input?: I) {
this._input = input;
}
init() {
- for (const id in this._lines) {
- let l = this._lines[id];
+ for (const id in this.lines) {
+ let l = this.lines[id];
l._id = id;
l.form = this;
}
}
getLine<K extends keyof L>(id: K): L[K] {
- if (!(id in this._lines))
+ if (!(id in this.lines))
throw new NotFoundError(`Form ${this.name} does not have line ${id}`);
- return this._lines[id];
+ return this.lines[id];
}
getValue<K extends keyof L>(tr: TaxReturn, id: K): ReturnType<L[K]['value']> {
});
test('reference line', () => {
- class TestForm extends Form<TestForm['_lines']> {
+ class TestForm extends Form<TestForm['lines']> {
readonly name = 'Form 1';
- protected readonly _lines = {
+ readonly lines = {
'6b': new ConstantLine(12.34),
's': new ConstantLine('abc'),
};
});
test('self reference line', () => {
- class OtherForm extends Form<OtherForm['_lines']> {
+ class OtherForm extends Form<OtherForm['lines']> {
readonly name = 'Form A';
- protected readonly _lines = {
+ readonly lines = {
'6c': new ConstantLine(55)
};
};
- class TestForm extends Form<TestForm['_lines']> {
+ class TestForm extends Form<TestForm['lines']> {
readonly name = 'Form 1';
- protected readonly _lines = {
+ readonly lines = {
'a': new ConstantLine(100.2),
'b': new ReferenceLine(OtherForm, '6c'),
'c': new ReferenceLine((TestForm as unknown) as FormClass<Form<any>>, 'b'),
key: string;
key2?: string;
}
- class TestForm extends Form<TestForm['_lines'], Input> {
+ class TestForm extends Form<TestForm['lines'], Input> {
readonly name = 'F1';
- protected readonly _lines = {
+ readonly lines = {
'1': new InputLine<Input>('key'),
'2': new InputLine<Input>('key2'),
'3': new InputLine<Input>('key2', undefined, 'FALLBACK')
});
test('line stack', () => {
- class FormZ extends Form<FormZ['_lines'], {'input': number}> {
+ class FormZ extends Form<FormZ['lines'], {'input': number}> {
readonly name = 'Z';
- protected readonly _lines = {
+ readonly lines = {
'3': new InputLine<any, any>('input')
}
};
- class FormZ2 extends Form<FormZ2['_lines']> {
+ class FormZ2 extends Form<FormZ2['lines']> {
readonly name = 'Z-2';
- protected readonly _lines = {
+ readonly lines = {
'2c': new ComputedLine<number>((tr: TaxReturn): any => {
return tr.getForm(FormZ).getLine('3').value(tr) * 0.2;
})
});
test('accumulator line', () => {
- class TestForm extends Form<TestForm['_lines']> {
+ class TestForm extends Form<TestForm['lines']> {
readonly name = 'Form B';
readonly supportsMultipleCopies = true;
- protected readonly _lines = {
+ readonly lines = {
g: new ConstantLine<number>(100.25)
};
};
test('single-copy forms', () => {
class TestForm extends Form<null> {
readonly name = 'Test Form';
- protected readonly _lines = null;
+ readonly lines = null;
};
const tr = new TestTaxReturn();
class TestForm extends Form<null> {
readonly name = 'Test Form';
readonly supportsMultipleCopies = true;
- protected readonly _lines = null;
+ readonly lines = null;
};
const tr = new TestTaxReturn();
test('get non-existent form', () => {
class TestForm extends Form<null> {
readonly name = 'Test Form';
- protected readonly _lines = null;
+ readonly lines = null;
}
const tr = new TestTaxReturn();
expect(() => tr.getForm(TestForm)).toThrow(NotFoundError);
expect(tr.findForms(TestForm)).toEqual([]);
});
-class PerPersonForm extends Form<PerPersonForm['_lines']> {
+class PerPersonForm extends Form<PerPersonForm['lines']> {
private _person?: Person;
readonly name = 'Per Person';
readonly supportsMultipleCopies = true;
- protected readonly _lines = {};
+ readonly lines = {};
constructor(person?: Person) {
super(undefined);
value: number;
};
-class TestForm extends Form<TestForm['_lines'], Input> {
+class TestForm extends Form<TestForm['lines'], Input> {
readonly name = 'TF';
- readonly _lines = {
+ readonly lines = {
'i1': new InputLine<Input>('name'),
'i2': new InputLine<Input>('value'),
'c1': new ComputedLine((tr): string => {
filingStatus: FilingStatus;
};
-export default class Form1040 extends Form<Form1040['_lines'], Form1040Input> {
+export default class Form1040 extends Form<Form1040['lines'], Form1040Input> {
readonly name = '1040';
- protected readonly _lines = {
+ readonly lines = {
'1': new AccumulatorLine(W2, '1', 'Wages, salaries, tips, etc.'),
'2a': new ComputedLine((tr): number => {
const value = (new AccumulatorLine(Form1099INT, '8')).value(tr) +
return ((income - bracketStart) * bracket[1]) + bracket[2];
};
-export class QDCGTaxWorksheet extends Form<QDCGTaxWorksheet['_lines']> {
+export class QDCGTaxWorksheet extends Form<QDCGTaxWorksheet['lines']> {
readonly name = 'QDCG Tax Worksheet';
- protected readonly _lines = {
+ readonly lines = {
'1': new ReferenceLine(Form1040, '11b', 'Taxable income'),
'2': new ReferenceLine(Form1040, '3a', 'Qualified dividends'),
'3': new ComputedLine((tr): number => {
class Input<T extends keyof Form1099BInput> extends InputLine<Form1099BInput, T> {};
-export default class Form1099B extends Form<Form1099B['_lines'], Form1099BInput> {
+export default class Form1099B extends Form<Form1099B['lines'], Form1099BInput> {
readonly name = '1099-B';
readonly supportsMultipleCopies = true;
person() { return this.getInput('payee'); }
- protected readonly _lines = {
+ readonly lines = {
'payer': new Input('payer'),
'recipient': new Input('payee'),
'shortTermBasisReported': new Input('shortTermBasisReported'),
class Input<T extends keyof Form1099DIVInput> extends InputLine<Form1099DIVInput, T> {};
-export default class Form1099DIV extends Form<Form1099DIV['_lines'], Form1099DIVInput> {
+export default class Form1099DIV extends Form<Form1099DIV['lines'], Form1099DIVInput> {
readonly name = '1099-DIV';
readonly supportsMultipleCopies = true;
person() { return this.getInput('payee'); }
- protected readonly _lines = {
+ readonly lines = {
'payer': new Input('payer'),
'recipient': new Input('payee'),
'1a': new Input('ordinaryDividends', undefined, 0),
class Input<T extends keyof Form1099INTInput> extends InputLine<Form1099INTInput, T> {};
-export default class Form1099INT extends Form<Form1099INT['_lines'], Form1099INTInput> {
+export default class Form1099INT extends Form<Form1099INT['lines'], Form1099INTInput> {
readonly name = '1099-INT';
readonly supportsMultipleCopies = true;
person() { return this.getInput('payee'); }
- protected readonly _lines = {
+ readonly lines = {
'payer': new Input('payer'),
'recipient': new Input('payee'),
'1': new Input('interest'),
class Input<T extends keyof Form1099RInput> extends InputLine<Form1099RInput, T> {};
-export default class Form1099R extends Form<Form1099R['_lines'], Form1099RInput> {
+export default class Form1099R extends Form<Form1099R['lines'], Form1099RInput> {
readonly name = '1099-R';
readonly supportsMultipleCopies = true;
person() { return this.getInput('payee'); }
- protected readonly _lines = {
+ readonly lines = {
'payer': new Input('payer'),
'recipeint': new Input('payee'),
'1': new Input('grossDistribution'),
class Input<T extends keyof Form1116Input> extends InputLine<Form1116Input, T> {};
-export default class Form1116 extends Form<Form1116['_lines'], Form1116Input> {
+export default class Form1116 extends Form<Form1116['lines'], Form1116Input> {
readonly name = '1116';
- protected readonly _lines = {
+ readonly lines = {
'category': new ComputedLine((tr: TaxReturn): ForeignIncomeCategory => {
const input = this.getInput('incomeCategory');
if (input != ForeignIncomeCategory.C)
class Input<T extends keyof Form8606Input> extends InputLine<Form8606Input, T> {};
-export default class Form8606 extends Form<Form8606['_lines'], Form8606Input> {
+export default class Form8606 extends Form<Form8606['lines'], Form8606Input> {
readonly name = '8606';
readonly supportsMultipleCopies = true;
person() { return this.getInput('person'); }
- protected readonly _lines = {
+ readonly lines = {
'person': new Input('person'),
// Part 1
}
};
-export default class Form8949 extends Form<Form8949['_lines']> {
+export default class Form8949 extends Form<Form8949['lines']> {
readonly name = '8949';
readonly supportsMultipleCopies = true;
- protected readonly _lines = {
+ readonly lines = {
'boxA': new Form8949Line(Form8949Box.A),
'boxB': new Form8949Line(Form8949Box.B),
'boxC': new Form8949Line(Form8949Box.C),
import Form1040, { FilingStatus } from './Form1040';
import W2 from './W2';
-export default class Form8959 extends Form<Form8959['_lines']> {
+export default class Form8959 extends Form<Form8959['lines']> {
readonly name = '8959';
- protected readonly _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)
import Form1040, { FilingStatus } from './Form1040';
import Schedule1 from './Schedule1';
-export default class Form8960 extends Form<Form8960['_lines']> {
+export default class Form8960 extends Form<Form8960['lines']> {
readonly name = '8960';
- protected readonly _lines = {
+ readonly lines = {
// Part 1
// Section 6013 elections not supported.
'1': new ReferenceLine(Form1040, '2b', 'Taxable interest'),
// Dividends from REITs get preferential tax treatment, but the form used to
// calculate that differs based off taxable income amounts. But the QBI
// computation for RETIs is the same. This just models the REIT portion.
-export default class Form8995REIT extends Form<Form8995REIT['_lines']> {
+export default class Form8995REIT extends Form<Form8995REIT['lines']> {
readonly name = '8995 REIT';
// This uses line numbers from 8995-A.
- protected readonly _lines = {
+ readonly lines = {
// 1-26 not supported
'27': new ComputedLine(() => 0, 'Total qualified business income component'), // Not supported.
'28': new AccumulatorLine(Form1099DIV, '5', 'Qualified REIT dividends'),
}
};
-export default class Schedule1 extends Form<Schedule1['_lines'], Schedule1Input> {
+export default class Schedule1 extends Form<Schedule1['lines'], Schedule1Input> {
readonly name = 'Schedule 1';
- readonly _lines = {
+ readonly lines = {
// Part 1
'1': new ComputedLine((tr): number => {
if (this.hasInput('stateAndLocalTaxableRefunds'))
prevYearFilingStatus?: FilingStatus;
};
-export class SALTWorksheet extends Form<SALTWorksheet['_lines'], SALTWorksheetInput> {
+export class SALTWorksheet extends Form<SALTWorksheet['lines'], SALTWorksheetInput> {
readonly name = 'SALT Refund Worksheet';
- protected readonly _lines = {
+ readonly lines = {
'1': new ComputedLine((tr): number => {
const refunds = tr.findForm(Schedule1).getInput('stateAndLocalTaxableRefunds');
const prevYear = this.getInput('prevYearSalt');
import Form8959 from './Form8959';
import Form8960 from './Form8960';
-export default class Schedule2 extends Form<Schedule2['_lines']> {
+export default class Schedule2 extends Form<Schedule2['lines']> {
readonly name = 'Schedule 2';
- protected readonly _lines = {
+ readonly lines = {
'1': new ComputedLine((tr): number => {
// TODO - this is just using Taxable Income, rather than AMT-limited
// income
estimatedTaxPayments?: number;
};
-export default class Schedule3 extends Form<Schedule3['_lines'], Schedule3Input> {
+export default class Schedule3 extends Form<Schedule3['lines'], Schedule3Input> {
readonly name = 'Schedule 3';
- readonly _lines = {
+ readonly lines = {
// Part 1
'1': new ComputedLine((tr): number => {
const f1040 = tr.getForm(Form1040);
import Form1099DIV from './Form1099DIV';
import Form1040, { FilingStatus, QDCGTaxWorksheet, computeTax } from './Form1040';
-export default class ScheduleD extends Form<ScheduleD['_lines']> {
+export default class ScheduleD extends Form<ScheduleD['lines']> {
readonly name = 'Schedule D';
- protected readonly _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)
};
};
-export class ScheduleDTaxWorksheet extends Form<ScheduleDTaxWorksheet['_lines']> {
+export class ScheduleDTaxWorksheet extends Form<ScheduleDTaxWorksheet['lines']> {
readonly name = 'Schedule D Tax Worksheet';
- protected readonly _lines = {
+ readonly lines = {
'1': new ReferenceLine(Form1040, '11b'),
'2': new ReferenceLine(Form1040, '3a'),
// TODO 3 - form 4952
class Input<T extends keyof W2Input> extends InputLine<W2Input, T> {};
-export default class W2 extends Form<W2['_lines'], W2Input> {
+export default class W2 extends Form<W2['lines'], W2Input> {
readonly name = 'W-2';
readonly supportsMultipleCopies = true;
return this.getInput('employee');
}
- protected readonly _lines = {
+ readonly lines = {
'c': new Input('employer', 'Employer name'),
'e': new Input('employee', 'Emplyee name'),
'1': new Input('wages', 'Wages, tips, other compensation'),