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