Add Schedule 1.
[ustaxlib.git] / src / fed2019 / Schedule1.ts
1 import Form from '../Form';
2 import TaxReturn from '../TaxReturn';
3 import { ComputedLine, InputLine } from '../Line';
4 import { NotFoundError, UnsupportedFeatureError } from '../Errors';
5 import { undefinedToZero } from '../Math';
6
7 import Form1040 from './Form1040';
8
9 export interface Schedule1Input {
10 // Additional Income
11 stateAndLocalTaxableRefunds?: number;
12 alimonyReceived?: number;
13 businessIncome?: number;
14 otherGainsOrLosses?: number
15 rentalRealEstateRoyaltiesPartnershipsSCorps?: number;
16 farmIncome?: number;
17 unemploymentCompensation?: number;
18 otherIncome?: number;
19
20 // Adjustments
21 educatorExpenses?: number;
22 businessExpensesForm2106?: number;
23 hsaDeduction?: number;
24 armedForcesMovingExpenses?: number;
25 deductibleSelfEmploymentTax?: number;
26 selfEmployedSepSimpleQualifiedPlans?: number;
27 selfEmployedHealthInsuranceDeduction?: number;
28 penaltyOnEarlyWithdrawal?: number;
29 alimonyPaid?: number;
30 iraDeduction?: number;
31 studentLoanInterestDeduction?: number;
32 tuitionAndFees?: number;
33 };
34
35 class Input<T extends keyof Schedule1Input> extends InputLine<Schedule1Input, T> {
36 private _predicate: (value: Schedule1Input[T]) => void;
37
38 constructor(input: T, predicate?: (value: Schedule1Input[T]) => void) {
39 super(input);
40 this._predicate = predicate;
41 }
42
43 value(tr: TaxReturn): Schedule1Input[T] {
44 let value: Schedule1Input[T] = undefined;
45 try {
46 value = super.value(tr);
47 } catch (NotFoundError) {
48 }
49 if (this._predicate)
50 this._predicate(value);
51 return value;
52 }
53 };
54
55 export default class Schedule1 extends Form<Schedule1['_lines'], Schedule1Input> {
56 readonly name = 'Schedule 1';
57
58 readonly _lines = {
59 // Part 1
60 '1': new Input('stateAndLocalTaxableRefunds'),
61 '2': new Input('alimonyReceived'),
62 '3': new Input('businessIncome', (value: number) => {
63 if (value !== undefined)
64 throw new UnsupportedFeatureError('Schedule C not supported');
65 }),
66 '4': new Input('otherGainsOrLosses', (value: number) => {
67 if (value !== undefined)
68 throw new UnsupportedFeatureError('Form 4797 not supported');
69 }),
70 '5': new Input('rentalRealEstateRoyaltiesPartnershipsSCorps', (value: number) => {
71 if (value !== undefined)
72 throw new UnsupportedFeatureError('Schedule E not supported');
73 }),
74 '6': new Input('farmIncome', (value: number) => {
75 if (value !== undefined)
76 throw new UnsupportedFeatureError('Schedule F not supported');
77 }),
78 '7': new Input('unemploymentCompensation'),
79 '8': new Input('otherIncome'),
80 '9': new ComputedLine((tr): number => {
81 return undefinedToZero(this.getValue(tr, '1')) +
82 undefinedToZero(this.getValue(tr, '2')) +
83 undefinedToZero(this.getValue(tr, '3')) +
84 undefinedToZero(this.getValue(tr, '4')) +
85 undefinedToZero(this.getValue(tr, '5')) +
86 undefinedToZero(this.getValue(tr, '6')) +
87 undefinedToZero(this.getValue(tr, '7')) +
88 undefinedToZero(this.getValue(tr, '8'));
89 }),
90
91 // Part 2
92 '10': new Input('educatorExpenses'),
93 '11': new Input('businessExpensesForm2106', (value: number) => {
94 if (value !== undefined)
95 throw new UnsupportedFeatureError('Form 2106 not supported');
96 }),
97 '12': new Input('hsaDeduction', (value: number) => {
98 if (value !== undefined)
99 throw new UnsupportedFeatureError('Form 8889 not supported');
100 }),
101 '13': new Input('armedForcesMovingExpenses', (value: number) => {
102 if (value !== undefined)
103 throw new UnsupportedFeatureError('Form 3903 not supported');
104 }),
105 '14': new Input('deductibleSelfEmploymentTax', (value: number) => {
106 if (value !== undefined)
107 throw new UnsupportedFeatureError('Schedule SE not supported');
108 }),
109 '15': new Input('selfEmployedSepSimpleQualifiedPlans'),
110 '16': new Input('selfEmployedHealthInsuranceDeduction'),
111 '17': new Input('penaltyOnEarlyWithdrawal'),
112 '18': new Input('alimonyPaid'),
113 '19': new Input('iraDeduction'),
114 '20': new Input('studentLoanInterestDeduction'),
115 '21': new Input('tuitionAndFees', (value: number) => {
116 if (value !== undefined)
117 throw new UnsupportedFeatureError('Form 8917 not supported');
118 }),
119 '22': new ComputedLine((tr): number => {
120 return undefinedToZero(this.getValue(tr, '10')) +
121 undefinedToZero(this.getValue(tr, '11')) +
122 undefinedToZero(this.getValue(tr, '12')) +
123 undefinedToZero(this.getValue(tr, '13')) +
124 undefinedToZero(this.getValue(tr, '14')) +
125 undefinedToZero(this.getValue(tr, '15')) +
126 undefinedToZero(this.getValue(tr, '16')) +
127 undefinedToZero(this.getValue(tr, '17')) +
128 undefinedToZero(this.getValue(tr, '18')) +
129 undefinedToZero(this.getValue(tr, '19')) +
130 undefinedToZero(this.getValue(tr, '20')) +
131 undefinedToZero(this.getValue(tr, '21'));
132 }),
133 };
134 };