lp1847519 Port of Circulation Limit Set UI
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / admin / local / circ_limit_set / circ_limit_set_edit.component.ts
1 import {Component, OnInit, Input, ViewChild} from '@angular/core';
2 import {ActivatedRoute} from '@angular/router';
3 import {PcrudService} from '@eg/core/pcrud.service';
4 import {StringComponent} from '@eg/share/string/string.component';
5 import {ToastService} from '@eg/share/toast/toast.service';
6 import {OrgService} from '@eg/core/org.service';
7 import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
8 import {IdlService } from '@eg/core/idl.service';
9 import {NgbNav, NgbNavChangeEvent} from '@ng-bootstrap/ng-bootstrap';
10
11 @Component({
12     templateUrl: './circ_limit_set_edit.component.html'
13 })
14
15 export class CircLimitSetEditComponent  implements OnInit {
16     recordId: number;
17     recordName: String;
18     locations: any[];
19     circMods: any[];
20     allCircMods: any[];
21     limitGroups: any[];
22     allLimitGroups: any[];
23     selectedCircMod: any;
24     selectedLocation: any;
25     selectedLimitGroup: any;
26     locId = 0;
27
28     circTab: 'limitSet' | 'linked' = 'limitSet';
29
30     @ViewChild('addingSuccess', {static: true}) addingSuccess: StringComponent;
31     @ViewChild('removingSuccess', {static: true}) removingSuccess: StringComponent;
32     @ViewChild('savingEntryError', {static: true}) savingEntryError: StringComponent;
33     @ViewChild('deletingEntryError', {static: true}) deletingEntryError: StringComponent;
34     @ViewChild('updatingEntryError', {static: true}) updatingEntryError: StringComponent;
35     @ViewChild('savedSuccess', {static: true}) savedSuccess: StringComponent;
36
37     constructor(
38         private org: OrgService,
39         private route: ActivatedRoute,
40         private pcrud: PcrudService,
41         private toast: ToastService,
42         private idl: IdlService,
43     ) {
44         this.locations = [];
45         this.circMods = [];
46         this.allCircMods = [];
47         this.limitGroups = [];
48         this.allLimitGroups = [];
49     }
50
51     ngOnInit() {
52         this.recordId = parseInt(this.route.snapshot.paramMap.get('id'), 10);
53
54         // get current circ limit set name to display on the banner
55         this.pcrud.search('ccls',
56             {id: this.recordId}, {}).toPromise().then(rec => {
57             this.recordName = rec.name();
58         });
59
60         this.pcrud.search('cclscmm', {limit_set: this.recordId},
61         {
62             flesh: 1,
63             flesh_fields: {cclscmm: ['circ_mod', 'name', 'code']},
64             order_by: {}
65         }).subscribe(data => {
66             data.deleted = false;
67             data.name = data.circ_mod().name();
68             data.code = data.circ_mod().code();
69             this.circMods.push(data);
70         });
71
72         this.pcrud.retrieveAll('ccm', { order_by: {} },
73             {fleshSelectors: true}).subscribe(data => {
74             this.allCircMods.push(data);
75         });
76
77         this.pcrud.retrieveAll('cclg', { order_by: {} },
78             {fleshSelectors: true}).subscribe(data => {
79                 this.allLimitGroups.push(data);
80         });
81
82         this.pcrud.search('cclsacpl', {limit_set: this.recordId},
83         {
84             flesh: 1,
85             flesh_fields: {cclsacpl: ['copy_loc', 'name']},
86             order_by: {}
87         }).subscribe(location => {
88             location.deleted = false;
89             location.shortname = this.org.get(location.copy_loc().owning_lib()).shortname();
90             location.name = location.copy_loc().name();
91             this.locations.push(location);
92         });
93
94         this.pcrud.search('cclsgm', {limit_set: this.recordId},
95         {
96             flesh: 1,
97             flesh_fields: {cclsgm: ['limit_group', 'check_only']},
98             order_by: {}
99         }).subscribe(data => {
100             const checked = data.check_only();
101             data.checked = (checked === 't');
102             data.checkedOriginalValue = (checked === 't');
103             data.name = data.limit_group().name();
104             data.deleted = false;
105             this.limitGroups.push(data);
106         });
107     }
108
109     onTabChange(event: NgbNavChangeEvent) {
110         this.circTab = event.nextId;
111     }
112
113     addLocation() {
114         if (!this.selectedLocation) { return; }
115         const newCircModMap = this.idl.create('cclsacpl');
116         newCircModMap.copy_loc(this.selectedLocation);
117         newCircModMap.limit_set(this.recordId);
118         newCircModMap.shortname =
119             this.org.get(this.selectedLocation.owning_lib()).shortname();
120         newCircModMap.name = this.selectedLocation.name();
121         newCircModMap.new = true;
122         newCircModMap.deleted = false;
123         this.locations.push(newCircModMap);
124         this.addingSuccess.current().then(msg => this.toast.success(msg));
125     }
126
127     addCircMod() {
128         if (!this.selectedCircMod) { return; }
129         const newName = this.selectedCircMod.name;
130         const newCode = this.selectedCircMod.code;
131         const newCircModMap = this.idl.create('cclscmm');
132         newCircModMap.limit_set(this.recordId);
133         newCircModMap.name = newName;
134         newCircModMap.code = newCode;
135         newCircModMap.new = true;
136         newCircModMap.deleted = false;
137         let newCircMod: any;
138         this.allCircMods.forEach(c => {
139             if ((c.name() === newName) && (c.code() === newCode)) {
140                 newCircMod = this.idl.clone(c);
141             }
142         });
143         newCircModMap.circ_mod(newCircMod);
144         this.circMods.push(newCircModMap);
145         this.addingSuccess.current().then(msg => this.toast.success(msg));
146     }
147
148     circModChanged(entry: ComboboxEntry) {
149         if (entry) {
150             this.selectedCircMod = {
151                 code: entry.id,
152                 name: entry.label
153             };
154         } else {
155             this.selectedCircMod = null;
156         }
157     }
158
159     removeLocation(location) {
160         const id = location.copy_loc().id();
161         if (location.new) {
162             this.locations.forEach((loc, index) => {
163                 if (loc.copy_loc().id() === id) {
164                     this.locations.splice(index, 1);
165                 }
166             });
167         }
168         location.deleted = true;
169         this.removingSuccess.current().then(msg => this.toast.success(msg));
170     }
171
172     removeEntry(entry, array) {
173         // if we haven't saved yet, then remove this entry from local array
174         if (entry.new) {
175             const name = entry.name;
176             array.forEach((item, index) => {
177                 if (item.name === name) {
178                     array.splice(index, 1);
179                 }
180             });
181         }
182         entry.deleted = true;
183         this.removingSuccess.current().then(msg => this.toast.success(msg));
184     }
185
186     addLimitGroup() {
187         if (!this.selectedLimitGroup) { return; }
188         const newName = this.selectedLimitGroup.name;
189         let undeleting = false;
190         this.limitGroups.forEach(group => {
191             if (newName === group.name) {
192                 if (group.deleted === true) {
193                     group.deleted = false;
194                     undeleting = true;
195                     this.addingSuccess.current().then(msg => this.toast.success(msg));
196                 }
197             }
198         });
199         if (undeleting) { return; }
200         const newLimitGroupMap = this.idl.create('cclsgm');
201         newLimitGroupMap.limit_set(this.recordId);
202         newLimitGroupMap.name = newName;
203         newLimitGroupMap.new = true;
204         newLimitGroupMap.checked = false;
205         newLimitGroupMap.check_only(false);
206         newLimitGroupMap.deleted = false;
207         let newLimitGroup: any;
208         this.allLimitGroups.forEach(c => {
209             if (c.name() === newName) {
210                 newLimitGroup = this.idl.clone(c);
211             }
212         });
213         newLimitGroupMap.limit_group(newLimitGroup);
214         this.limitGroups.push(newLimitGroupMap);
215         this.addingSuccess.current().then(msg => this.toast.success(msg));
216     }
217
218     limitGroupChanged(entry: ComboboxEntry) {
219         if (entry) {
220             this.selectedLimitGroup = {
221                 name: entry.label,
222                 checked: false
223             };
224         } else {
225             this.selectedLimitGroup = null;
226         }
227     }
228
229     save() {
230         const allData = [this.circMods, this.locations, this.limitGroups];
231         let errorOccurred = false;
232         allData.forEach( array => {
233             array.forEach((item) => {
234                 if (item.new) {
235                     if (array === this.limitGroups) {
236                         item.check_only(item.checked);
237                     }
238                     this.pcrud.create(item).subscribe(
239                         ok => {
240                             const id = ok.id();
241                             item.id(id);
242                             item.new = false;
243                             if (array === this.limitGroups) {
244                                 item.checkedOriginalValue = item.checked;
245                             }
246                         },
247                         err => {
248                             errorOccurred = true;
249                             this.savingEntryError.current().then(msg =>
250                                 this.toast.warning(msg));
251                         }
252                     );
253                 // only delete this from db if we haven't deleted it before
254                 } else if ((item.deleted) && (!item.deletedSuccess)) {
255                     this.pcrud.remove(item).subscribe(
256                         ok => {
257                             item.deletedSuccess = true;
258                         },
259                         err => {
260                             errorOccurred = true;
261                             this.deletingEntryError.current().then(msg =>
262                                 this.toast.warning(msg));
263                         }
264                     );
265                 // check limit group items to see if the checkbox changed since last write
266                 } else if ((array === this.limitGroups) && (!item.deleted) &&
267                     (!item.new) && (item.checked !== item.checkedOriginalValue)) {
268                     item.check_only(item.checked);
269                     this.pcrud.update(item).subscribe(
270                         ok => {
271                             item.checkedOriginalValue = item.checked;
272                         },
273                         err => {
274                             errorOccurred = true;
275                             this.updatingEntryError.current().then(msg =>
276                                 this.toast.warning(msg));
277                         }
278                     );
279                 }
280             });
281         });
282
283         if (!errorOccurred) {
284             this.savedSuccess.current().then(msg => this.toast.success(msg));
285         }
286     }
287 }