Revert "Make SupportsMultipleCopies an interface."
[ustaxlib.git] / src / Form.ts
1 import TaxReturn from './TaxReturn';
2 import { Line } from './Line';
3 import { InconsistencyError, NotFoundError } from './Errors';
4
5 export default abstract class Form<I = unknown> {
6 private _lines: Line<any>[] = [];
7 private _input?: I;
8
9 abstract get name(): string;
10
11 readonly supportsMultipleCopies: boolean = false;
12
13 constructor(input?: I) {
14 this._input = input;
15 this.getLines().map(this.addLine.bind(this));
16 }
17
18 protected abstract getLines(): Line<any>[];
19
20 private addLine(line: Line<any>) {
21 if (line.form !== undefined) {
22 throw new InconsistencyError('Line is already in a Form');
23 }
24 try {
25 this.getLine(line.id);
26 } catch {
27 line.form = this;
28 this._lines.push(line);
29 return;
30 }
31 throw new InconsistencyError('Cannot add a line with a duplicate identifier');
32 }
33
34 getLine(id: string): Line<any> {
35 const lines = this._lines.filter(l => l.id === id);
36 if (lines.length == 0) {
37 throw new NotFoundError(id);
38 }
39 return lines[0];
40 }
41
42 getValue<T>(tr: TaxReturn, id: string): T {
43 const line: Line<T> = this.getLine(id);
44 return line.value(tr);
45 }
46
47 getInput<K extends keyof I>(name: K): I[K] {
48 if (!(name in this._input)) {
49 throw new NotFoundError(`No input with key ${name} on form ${this.name}`);
50 }
51 return this._input[name];
52 }
53 };