Add Form 1099-INT.
[ustaxlib.git] / src / Line.ts
1 import TaxReturn from './TaxReturn';
2 import Form from './Form';
3
4 export abstract class Line<T> {
5 private _description?: string;
6
7 _id: string; // _id is set by Form.init().
8 form: Form<any, any>; // Set by Form.init();
9
10 constructor(description?: string) {
11 this._description = description;
12 }
13
14 get id(): string {
15 return this._id;
16 }
17
18 get description(): string {
19 return this._description;
20 }
21
22 abstract value(tr: TaxReturn): T;
23 };
24
25 type ComputeFunc<T> = (tr: TaxReturn, l: ComputedLine<T>) => T;
26
27 export class ComputedLine<T> extends Line<T> {
28 private _compute: ComputeFunc<T>;
29
30 constructor(compute: ComputeFunc<T>, description?: string) {
31 super(description);
32 this._compute = compute;
33 }
34
35 value(tr: TaxReturn): T {
36 return this._compute(tr, this);
37 }
38 };
39
40 export class ReferenceLine<T> extends Line<T> {
41 private _form: string;
42 private _line: string;
43
44 constructor(form: string, line: string, description?: string) {
45 super(description || `Reference F${form}.L${line}`);
46 this._form = form;
47 this._line = line;
48 }
49
50 value(tr: TaxReturn): T {
51 return tr.getForm(this._form).getLine(this._line).value(tr);
52 }
53 };
54
55 export class InputLine<U = unknown, T extends keyof U = any> extends Line<U[T]> {
56 private _input: T;
57
58 form: Form<any, U>;
59
60 constructor(input: T, description?: string) {
61 super(description || `Input from ${input}`);
62 this._input = input;
63 }
64
65 value(tr: TaxReturn): U[T] {
66 return this.form.getInput<T>(this._input);
67 }
68 };
69
70 export class AccumulatorLine extends Line<number> {
71 private _form: string;
72 private _line: string;
73
74 constructor(form: string, line: string, description?: string) {
75 super(description || `Accumulator F${form}.L${line}`);
76 this._form = form;
77 this._line = line;
78 }
79
80 value(tr: TaxReturn): number {
81 const forms = tr.getForms(this._form);
82 const reducer = (acc: number, curr: Form<any>) => acc + (curr.getValue(tr, this._line) as number);
83 return forms.reduce(reducer, 0);
84 }
85 };