import Form1040, { FilingStatus } from './Form1040';
import Form1099DIV from './Form1099DIV';
import Form1099INT from './Form1099INT';
-import Form1099B, { GainType } from './Form1099B';
+import Form1099B from './Form1099B';
import Form1099R, { Box7Code } from './Form1099R';
import Schedule2 from './Schedule2';
import ScheduleD, { ScheduleDTaxWorksheet } from './ScheduleD';
tr.addForm(new Form1099B({
payer: 'Brokerage',
payee: p,
- description: '10 FNDC',
- proceeds: 1000,
- costBasis: 800,
- gainType: GainType.LongTerm,
- basisReportedToIRS: true
+ longTermBasisReported: [
+ {
+ description: '10 FNDC',
+ proceeds: 1000,
+ costBasis: 800,
+ }
+ ]
}));
tr.addForm(new Form8949);
tr.addForm(new ScheduleD());
import { Form, Person, TaxReturn } from '../core';
import { InputLine } from '../core/Line';
-export enum GainType {
- ShortTerm = 'ST',
- LongTerm = 'LT',
- Ordinary = 'O',
-};
-
-export interface SpecialProceeds {
- collectibles?: boolean;
- qof?: boolean;
-};
-
-export interface IRSReporting {
- grossProceeds?: boolean;
- netProceeds?: boolean;
-};
-
-export interface Form1099BInput {
- payer: string;
- payee: Person;
+export interface Form1099BRow {
description: string;
dateAcquired?: string;
dateSold?: string;
costBasis: number;
accruedMarketDiscount?: number;
washSaleLossDisallowed?: number;
- gainType: GainType;
- specialProceeds?: SpecialProceeds;
fedIncomeTax?: number;
- nonCoveredSecurity?: boolean;
- irsReporting?: IRSReporting;
- disallowedLoss?: boolean;
- profitOnClosedContracts?: number;
- unrealizedProfitOnOpenContractsCurrentTY?: number;
- unrealizedProfitOnOpenContractsNextTY?: number;
- aggregateProfitOnContracts?: number;
- basisReportedToIRS?: boolean;
- bartering?: number;
+
+ adjustments?: number; // Not reported on 1099-B, but entered as part of Form8994.
+};
+
+export interface Form1099BInput {
+ payer: string;
+ payee: Person;
+
+ shortTermBasisReported?: Form1099BRow[]; // Box A checked.
+ shortTermBasisUnreported?: Form1099BRow[]; // Box B checked.
+
+ longTermBasisReported?: Form1099BRow[]; // Box D checked.
+ longTermBasisUnreported?: Form1099BRow[]; // Box E checked.
+
+ // For unreported securities, create your own 1099-B.
+ shortTermUnreported?: Form1099BRow[]; // Box C checked.
+ longTermUnreported?: Form1099BRow[]; // Box F checked.
};
class Input<T extends keyof Form1099BInput> extends InputLine<Form1099BInput, T> {};
protected readonly _lines = {
'payer': new Input('payer'),
'recipient': new Input('payee'),
- '1a': new Input('description'),
- '1b': new Input('dateAcquired'),
- '1c': new Input('dateSold'),
- '1d': new Input('proceeds'),
- '1e': new Input('costBasis'),
- '1f': new Input('accruedMarketDiscount'),
- '1g': new Input('washSaleLossDisallowed'),
- '2': new Input('gainType'),
- '3': new Input('specialProceeds'),
- '4': new Input('fedIncomeTax'),
- '5': new Input('nonCoveredSecurity'),
- '6': new Input('irsReporting'),
- '7': new Input('disallowedLoss'),
- '8': new Input('profitOnClosedContracts'),
- '9': new Input('unrealizedProfitOnOpenContractsCurrentTY'),
- '10': new Input('unrealizedProfitOnOpenContractsNextTY'),
- '11': new Input('aggregateProfitOnContracts'),
- '12': new Input('basisReportedToIRS'),
- '13': new Input('bartering')
+ 'shortTermBasisReported': new Input('shortTermBasisReported'),
+ 'shortTermBasisUnreported': new Input('shortTermBasisUnreported'),
+ 'longTermBasisReported': new Input('longTermBasisReported'),
+ 'longTermBasisUnreported': new Input('longTermBasisUnreported'),
+ 'shortTermUnreported': new Input('shortTermUnreported'),
+ 'longTermUnreported': new Input('longTermUnreported'),
};
};
import Form1040, { FilingStatus } from './Form1040';
import Form1116, { ForeignIncomeCategory } from './Form1116';
-import Form1099B, { GainType } from './Form1099B';
+import Form1099B from './Form1099B';
import Form1099DIV from './Form1099DIV';
import Form8949 from './Form8949';
import W2 from './W2';
tr.addForm(new Form1099B({
payer: 'Brokerage',
payee: p,
- description: 'SCHF',
- proceeds: 100,
- costBasis: 50,
- gainType: GainType.LongTerm,
- basisReportedToIRS: true
- }));
- tr.addForm(new Form1099B({
- payer: 'Brokerage',
- payee: p,
- description: 'SCHE',
- proceeds: 60,
- costBasis: 100,
- gainType: GainType.ShortTerm,
- basisReportedToIRS: true
+ longTermBasisReported: [
+ {
+ description: 'SCHF',
+ proceeds: 100,
+ costBasis: 50,
+ }
+ ],
+ shortTermBasisReported: [
+ {
+ description: 'SCHE',
+ proceeds: 60,
+ costBasis: 100,
+ }
+ ]
}));
tr.addForm(new Form8949);
tr.addForm(new ScheduleD);
import { Person } from '../core';
import Form1040, { FilingStatus } from './Form1040';
-import Form1099B, { GainType } from './Form1099B';
+import Form1099B, { Form1099BInput } from './Form1099B';
import Form8949, { Form8949Box, Form8949Total } from './Form8949';
import TaxReturn from './TaxReturn';
const tr = new TaxReturn();
tr.addPerson(p);
tr.addForm(new Form1040({ filingStatus: FilingStatus.Single }));
+
+ const fieldMap: { [key: string]: keyof Form1099BInput } = {
+ [Form8949Box.A]: 'shortTermBasisReported',
+ [Form8949Box.B]: 'shortTermBasisUnreported',
+ [Form8949Box.C]: 'shortTermUnreported',
+ [Form8949Box.D]: 'longTermBasisReported',
+ [Form8949Box.E]: 'longTermBasisUnreported',
+ [Form8949Box.F]: 'longTermUnreported',
+ };
+ const field = fieldMap[box];
+
tr.addForm(new Form1099B({
payer: 'Brokerage',
payee: p,
- description: '10 shares',
- proceeds: 100,
- costBasis: 110,
- gainType: (box == Form8949Box.A || box == Form8949Box.B) ? GainType.ShortTerm : GainType.LongTerm,
- basisReportedToIRS: (box == Form8949Box.A || box == Form8949Box.D),
+ [field]: [
+ {
+ description: '10 shares',
+ proceeds: 100,
+ costBasis: 110,
+ }
+ ],
}));
const form = new Form8949();
tr.addForm(new Form1099B({
payer: 'Brokerage',
payee: p,
- description: '10 SCHB',
- proceeds: 55,
- costBasis: 50,
- gainType: GainType.ShortTerm,
- basisReportedToIRS: true,
- }));
- tr.addForm(new Form1099B({
- payer: 'Brokerage',
- payee: p,
- description: '10 SCHB',
- proceeds: 55,
- costBasis: 50,
- gainType: GainType.LongTerm,
- basisReportedToIRS: false,
- }));
- tr.addForm(new Form1099B({
- payer: 'Brokerage',
- payee: p,
- description: '10 SCHF',
- proceeds: 22.40,
- costBasis: 10.10,
- gainType: GainType.LongTerm,
- basisReportedToIRS: false,
+ shortTermBasisReported: [
+ {
+ description: '10 SCHB',
+ proceeds: 55,
+ costBasis: 50,
+ }
+ ],
+ longTermBasisUnreported: [
+ {
+ description: '10 SCHB',
+ proceeds: 55,
+ costBasis: 50,
+ },
+ {
+ description: '10 SCHF',
+ proceeds: 22.40,
+ costBasis: 10.10,
+ }
+ ],
}));
const form = new Form8949();
const b1 = new Form1099B({
payer: 'Brokerage',
payee: p,
- description: '10 SCHB',
- proceeds: 55,
- costBasis: 50,
- gainType: GainType.ShortTerm,
- basisReportedToIRS: false,
+ shortTermBasisUnreported: [
+ {
+ description: '10 SCHB',
+ proceeds: 55,
+ costBasis: 50,
+ adjustments: -10,
+ }
+ ],
+ longTermBasisUnreported: [
+ {
+ description: '10 SCHB',
+ proceeds: 18,
+ costBasis: 25,
+ adjustments: 90,
+ }
+ ],
+ longTermBasisReported: [
+ {
+ description: '10 SCHF',
+ proceeds: 22.40,
+ costBasis: 10.10,
+ }
+ ]
});
tr.addForm(b1);
- const b2 = new Form1099B({
- payer: 'Brokerage',
- payee: p,
- description: '10 SCHB',
- proceeds: 18,
- costBasis: 25,
- gainType: GainType.LongTerm,
- basisReportedToIRS: false,
- });
- tr.addForm(b2);
- tr.addForm(new Form1099B({
- payer: 'Brokerage',
- payee: p,
- description: '10 SCHF',
- proceeds: 22.40,
- costBasis: 10.10,
- gainType: GainType.LongTerm,
- basisReportedToIRS: true,
- }));
- const form = new Form8949({
- adjustments: [
- { entry: b1, code: 'W', amount: -10 },
- { entry: b2, code: 'W', amount: 90 },
- ]
- });
+ const form = new Form8949();
tr.addForm(form);
const boxB = form.getValue(tr, 'boxB');
import * as Trace from '../core/Trace';
import { Form, Person, TaxReturn } from '../core';
import { Line, InputLine, ComputedLine, sumLineOfForms } from '../core/Line';
+import { undefinedToZero } from '../core/Math';
-import Form1099B, { GainType } from './Form1099B';
+import Form1099B, { Form1099BRow, Form1099BInput } from './Form1099B';
export enum Form8949Box {
A = 'A', // Short-term transactions reported on Form(s) 1099-B showing basis was reported to the IRS
F = 'F', // Long-term transactions not reported to you on Form 1099-B
};
-export interface Adjustment {
- entry: Form1099B;
- code: string;
- amount: number;
-};
-
-export interface Form8949Input {
- adjustments?: Adjustment[];
-};
-
export interface Form8949Total {
proceeds: number;
costBasis: number;
gainOrLoss: number;
};
-function matching1099Bs(tr: TaxReturn, box: Form8949Box): Form1099B[] {
- return tr.findForms(Form1099B).filter(f => {
- const gainType: GainType = f.getValue(tr, '2');
- const basisReported: boolean = f.getValue(tr, '12');
-
- switch (box) {
- case Form8949Box.A:
- return gainType == GainType.ShortTerm && basisReported;
- case Form8949Box.B:
- return gainType == GainType.ShortTerm && !basisReported;
- case Form8949Box.D:
- return gainType == GainType.LongTerm && basisReported;
- case Form8949Box.E:
- return gainType == GainType.LongTerm && !basisReported;
- };
-
- return false;
- });
-}
-
class Form8949Line extends Line<Form8949Total> {
private _box: Form8949Box;
private _line: keyof Form1099B['lines'];
value(tr: TaxReturn): Form8949Total {
Trace.begin(this);
- const f1099bs = matching1099Bs(tr, this._box);
- const proceeds = sumLineOfForms(tr, f1099bs, '1d');
- const costBasis = sumLineOfForms(tr, f1099bs, '1e');
- const f8949 = tr.getForm(Form8949);
- const adjustments = !f8949.hasInput('adjustments') ? 0 :
- f8949.getInput('adjustments')
- .filter(a => f1099bs.includes(a.entry))
- .reduce((acc, curr) => acc + curr.amount, 0);
- Trace.end();
- return {
- proceeds,
- costBasis,
- adjustments,
- gainOrLoss: proceeds - costBasis + adjustments,
+
+ const f1099bs = tr.findForms(Form1099B);
+ const fieldMap: { [key: string]: keyof Form1099BInput } = {
+ [Form8949Box.A]: 'shortTermBasisReported',
+ [Form8949Box.B]: 'shortTermBasisUnreported',
+ [Form8949Box.C]: 'shortTermUnreported',
+ [Form8949Box.D]: 'longTermBasisReported',
+ [Form8949Box.E]: 'longTermBasisUnreported',
+ [Form8949Box.F]: 'longTermUnreported',
+ };
+ const field: keyof Form1099BInput = fieldMap[this._box];
+
+ const value = {
+ proceeds: 0,
+ costBasis: 0,
+ adjustments: 0,
+ gainOrLoss: 0
};
+
+ for (const f1099b of f1099bs) {
+ if (!f1099b.hasInput(field))
+ continue;
+
+ const rows = f1099b.getInput(field) as Form1099BRow[];
+ for (const row of rows) {
+ let { proceeds, costBasis, adjustments } = row;
+ adjustments = undefinedToZero(adjustments);
+ value.proceeds += proceeds;
+ value.costBasis += costBasis;
+ value.adjustments += adjustments;
+ value.gainOrLoss += proceeds - costBasis + adjustments;
+ }
+ }
+
+ Trace.end();
+ return value;
}
};
-export default class Form8949 extends Form<Form8949['_lines'], Form8949Input> {
+export default class Form8949 extends Form<Form8949['_lines']> {
readonly name = '8949';
readonly supportsMultipleCopies = true;
import W2 from './W2';
import Form1040, { FilingStatus } from './Form1040';
-import Form1099B, { GainType } from './Form1099B';
+import Form1099B from './Form1099B';
import Form1099DIV from './Form1099DIV';
import Form1099INT from './Form1099INT';
import Form8949 from './Form8949';
tr.addForm(new Form1099B({
payer: 'Brokerage',
payee: p,
- description: '100 VTI',
- proceeds: 4000,
- costBasis: 3500,
- gainType: GainType.LongTerm,
- basisReportedToIRS: true
+ longTermBasisReported: [
+ {
+ description: '100 VTI',
+ proceeds: 4000,
+ costBasis: 3500,
+ }
+ ]
}));
tr.addForm(new Form8949);
tr.addForm(new ScheduleD);
tr.addForm(new Form1099B({
payer: 'Brokerage',
payee: p,
- description: '100 VTI',
- proceeds: 4000,
- costBasis: 3500,
- gainType: GainType.LongTerm,
- basisReportedToIRS: true
+ longTermBasisReported: [
+ {
+ description: '100 VTI',
+ proceeds: 4000,
+ costBasis: 3500,
+ }
+ ]
}));
tr.addForm(new Form8949);
tr.addForm(new ScheduleD);
import { Person } from '../core';
import Form1040, { FilingStatus } from './Form1040';
-import Form1099B, { GainType } from './Form1099B';
+import Form1099B from './Form1099B';
import Form1099DIV from './Form1099DIV';
import Form8949 from './Form8949';
import Form8995REIT from './Form8995';
tr.addForm(new Form1099B({
payer: 'Brokerage2 ',
payee: p,
- description: '100 VTI',
- proceeds: 230000,
- costBasis: 221000,
- gainType: GainType.LongTerm,
- basisReportedToIRS: true
+ longTermBasisReported: [
+ {
+ description: '100 VTI',
+ proceeds: 230000,
+ costBasis: 221000,
+ }
+ ]
}));
tr.addForm(new Form8949);
tr.addForm(new ScheduleD);