1 import TaxReturn from './TaxReturn';
2 import Form from './Form';
4 export abstract class Line<T> {
5 private _description?: string;
7 _id: string; // _id is set by Form.init().
8 form: Form<any, any>; // Set by Form.init();
10 constructor(description?: string) {
11 this._description = description;
18 get description(): string {
19 return this._description;
22 abstract value(tr: TaxReturn): T;
25 type ComputeFunc<T> = (tr: TaxReturn, l: ComputedLine<T>) => T;
27 export class ComputedLine<T> extends Line<T> {
28 private _compute: ComputeFunc<T>;
30 constructor(compute: ComputeFunc<T>, description?: string) {
32 this._compute = compute;
35 value(tr: TaxReturn): T {
36 return this._compute(tr, this);
40 export class ReferenceLine<T> extends Line<T> {
41 private _form: string;
42 private _line: string;
44 constructor(form: string, line: string, description?: string) {
45 super(description || `Reference F${form}.L${line}`);
50 value(tr: TaxReturn): T {
51 return tr.getForm(this._form).getLine(this._line).value(tr);
55 export class InputLine<U = unknown, T extends keyof U = any> extends Line<U[T]> {
60 constructor(input: T, description?: string) {
61 super(description || `Input from ${input}`);
65 value(tr: TaxReturn): U[T] {
66 return this.form.getInput<T>(this._input);
70 export class AccumulatorLine extends Line<number> {
71 private _form: string;
72 private _line: string;
74 constructor(form: string, line: string, description?: string) {
75 super(description || `Accumulator F${form}.L${line}`);
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);