Introduce InputLine and the ability to acquire inputs from a TaxReturn.
[ustaxlib.git] / src / TaxReturn.ts
1 import Form from './Form';
2 import { Person, Relation } from './Person';
3 import { NotFoundError, InconsistencyError, UnsupportedFeatureError } from './Errors';
4
5 export default class TaxReturn {
6 private _year: number;
7 private _input: object;
8
9 private _people: Person[] = [];
10 private _forms: Form[] = [];
11
12 constructor(year: number, input?: object) {
13 this._year = year;
14 this._input = input;
15 }
16
17 get year(): number {
18 return this._year;
19 }
20
21 getInput<T>(name: string): T {
22 if (!(name in this._input)) {
23 throw new NotFoundError(`No input with key ${name}`);
24 }
25 return this._input[name] as T;
26 }
27
28 addPerson(person: Person) {
29 if (person.relation == Relation.Dependent) {
30 throw new UnsupportedFeatureError('Dependents are not supported');
31 }
32 if (person.relation == Relation.Self || person.relation == Relation.Spouse) {
33 const others = this._people.filter(p => p.relation == person.relation);
34 if (others.length > 0) {
35 throw new InconsistencyError('Cannot have more than one Self or Spouse');
36 }
37 }
38 this._people.push(person);
39 }
40
41 getPerson(name: RegExp | string): Person {
42 const people = this._people.filter(p => p.name.search(name) !== -1);
43 if (people.length != 1) {
44 throw new Error(`Person ${name} not found or too imprecise`);
45 }
46 return people[0];
47 }
48
49 addForm(form: Form) {
50 if (!form.allowMultipleCopies) {
51 const other = this.getForms(form.name);
52 if (other.length > 0) {
53 throw new InconsistencyError(`Cannot have more than one type of form ${form.name}`);
54 }
55 }
56 this._forms.push(form);
57 }
58
59 getForm(name: string): Form {
60 const forms = this.getForms(name);
61 if (forms.length == 0) {
62 throw new NotFoundError(`No form named ${name}`);
63 }
64 if (forms.length > 1) {
65 throw new InconsistencyError(`More than 1 form named ${name}`);
66 }
67 return forms[0];
68 }
69
70 getForms(name: string): Form[] {
71 return this._forms.filter(f => f.name == name);
72 }
73 };