Add support for Form 1098 and the mortgage interest deduction to Schedule A.
[ustaxlib.git] / src / fed2019 / ScheduleA.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 } from '../core';
7 import { Line, ComputedLine, InputLine, ReferenceLine, SymbolicLine, UnsupportedLine, sumFormLines } from '../core/Line';
8 import { clampToZero } from '../core/Math';
9
10 import Form1040, { FilingStatus } from './Form1040';
11 import { Form1098, MortgageInterestDeductionWorksheet } from './Form1098';
12
13 export interface ScheduleAInput {
14 medicalAndDentalExpenses?: number;
15
16 stateAndLocalIncomeAndSalesTaxes?: number;
17 stateAndLocalRealEstateTaxes?: number;
18 stateAndLocalPropertyTaxes?: number;
19 otherTaxes?: number;
20
21 // This form does not apply the mortgage interest limitations.
22 unreportedMortgageInterest?: number;
23 unreportedMortagePoints?: number;
24 mortgageInsurancePremiums?: number;
25 investmentInterest?: number;
26
27 charitableGiftsCashOrCheck?: number;
28 charitableGiftsOther?: number;
29 charitableCarryOver?: number;
30
31 casualtyAndTheftLosses?: number;
32
33 forceItemize?: boolean;
34 };
35
36 class Input extends InputLine<ScheduleAInput> {};
37
38 export default class ScheduleA extends Form<ScheduleAInput> {
39 readonly name = 'Schedule A';
40
41 readonly lines = {
42 // Medical and dental expenses
43 '1': new Input('medicalAndDentalExpenses', 'Medical and dental expenses', 0),
44 '2': new SymbolicLine(Form1040, 'adjustedGrossIncome'),
45 '3': new ComputedLine((tr): number => this.getValue(tr, '2') * tr.constants.medicalDeductionLimitationPercent),
46 '4': new ComputedLine((tr): number => clampToZero(this.getValue(tr, '1') - this.getValue(tr, '3'))),
47
48 // Taxes you paid
49 '5a': new Input('stateAndLocalIncomeAndSalesTaxes', 'State and local income taxes or general sales taxes', 0),
50 '5b': new Input('stateAndLocalRealEstateTaxes', 'State and local real estate taxes', 0),
51 '5c': new Input('stateAndLocalPropertyTaxes', 'State and local personal property taxes', 0),
52 '5d': new ComputedLine((tr): number => sumFormLines(tr, this, ['5a', '5b', '5c'])),
53 '5e': new ComputedLine((tr): number => {
54 const fs = tr.getForm(Form1040).filingStatus;
55 const limit = tr.constants.saltLimit[fs];
56 return Math.min(this.getValue(tr, '5d'), limit);
57 }),
58 '6': new Input('otherTaxes', 'Other taxes', 0),
59 '7': new ComputedLine((tr): number => sumFormLines(tr, this, ['5e', '6'])),
60
61 // Interest you paid
62 '8a': new ComputedLine((tr): number => {
63 if (tr.findForms(Form1098).length == 0)
64 return 0;
65 return tr.getForm(MortgageInterestDeductionWorksheet).deductibleMortgateInterest(tr);
66 }, 'Home mortgage interest and points'),
67 '8b': new Input('unreportedMortgageInterest', 'Home mortgage interest not reported on Form 1098', 0),
68 '8c': new Input('unreportedMortagePoints', 'Points not reported on Form 1098', 0),
69 '8d': new Input('mortgageInsurancePremiums', 'Mortgage insurance premiums', 0),
70 '8e': new ComputedLine((tr): number => sumFormLines(tr, this, ['8a', '8b', '8c', '8d'])),
71 '9': new Input('investmentInterest', 'Investment interest', 0),
72 '10': new ComputedLine((tr): number => sumFormLines(tr, this, ['8e', '9'])),
73
74 // Gifts to charity
75 '11': new Input('charitableGiftsCashOrCheck', 'Gifts by cash or check', 0),
76 '12': new Input('charitableGiftsOther', 'Other than by cash or check', 0),
77 '13': new Input('charitableCarryOver', 'Carryover from prior year', 0),
78 '14': new ComputedLine((tr): number => sumFormLines(tr, this, ['11', '12', '13'])),
79
80 '15': new Input('casualtyAndTheftLosses', 'Casualty and theft loss(es)', 0),
81
82 '17': new ComputedLine((tr): number => sumFormLines(tr, this, ['4', '7', '10', '14', '15'])),
83 '18': new Input('forceItemize', 'Itemize even if less than standard deduction', false),
84 };
85 };