]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/share/course.service.ts
LP2045292 Color contrast for AngularJS patron bills
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / share / course.service.ts
1 /* eslint-disable rxjs/no-nested-subscribe */
2 import { Observable, merge, throwError } from 'rxjs';
3 import { tap, switchMap } from 'rxjs/operators';
4 import {Injectable} from '@angular/core';
5 import {AuthService} from '@eg/core/auth.service';
6 import {EventService} from '@eg/core/event.service';
7 import {IdlObject, IdlService} from '@eg/core/idl.service';
8 import {NetService} from '@eg/core/net.service';
9 import {OrgService} from '@eg/core/org.service';
10 import {PcrudService} from '@eg/core/pcrud.service';
11
12 @Injectable()
13 export class CourseService {
14
15     constructor(
16         private auth: AuthService,
17         private evt: EventService,
18         private idl: IdlService,
19         private net: NetService,
20         private org: OrgService,
21         private pcrud: PcrudService
22     ) {}
23
24     isOptedIn(): Promise<any> {
25         return new Promise((resolve) => {
26             this.org.settings('circ.course_materials_opt_in').then(res => {
27                 resolve(res['circ.course_materials_opt_in']);
28             });
29         });
30     }
31     getCourses(course_ids?: Number[]): Promise<IdlObject[]> {
32         const flesher = {flesh: 2, flesh_fields: {
33             'acmc': ['owning_lib'],
34             'aou': ['ou_type']}};
35         if (!course_ids) {
36             return this.pcrud.retrieveAll('acmc',
37                 flesher, {atomic: true}).toPromise();
38         } else {
39             return this.pcrud.search('acmc', {id: course_ids},
40                 flesher, {atomic: true}).toPromise();
41         }
42     }
43
44     getMaterials(course_ids?: Number[]): Promise<IdlObject[]> {
45         if (!course_ids) {
46             return this.pcrud.retrieveAll('acmcm',
47                 {}, {atomic: true}).toPromise();
48         } else {
49             return this.pcrud.search('acmcm', {course: course_ids},
50                 {}, {atomic: true}).toPromise();
51         }
52     }
53
54     getUsers(course_ids?: Number[]): Observable<IdlObject> {
55         const flesher = {
56             flesh: 1,
57             flesh_fields: {'acmcu': ['usr', 'usr_role']}
58         };
59         if (!course_ids) {
60             return this.pcrud.retrieveAll('acmcu',
61                 flesher);
62         } else {
63             return this.pcrud.search('acmcu', {course: course_ids},
64                 flesher);
65         }
66     }
67
68     getCoursesFromMaterial(copy_id): Promise<any> {
69         const id_list = [];
70         return new Promise((resolve, reject) => {
71
72             return this.pcrud.search('acmcm', {item: copy_id})
73                 .subscribe(materials => {
74                     if (materials) {
75                         id_list.push(materials.course());
76                     }
77                 }, (err: unknown) => {
78                     console.debug(err);
79                     reject(err);
80                 }, () => {
81                     if (id_list.length) {
82                         return this.getCourses(id_list).then(courses => {
83                             resolve(courses);
84                         });
85                     }
86                 });
87         });
88     }
89
90     getTermMaps(term_ids) {
91         const flesher = {flesh: 2, flesh_fields: {
92             'acmtcm': ['course']}};
93
94         if (!term_ids) {
95             return this.pcrud.retrieveAll('acmtcm',
96                 flesher);
97         } else {
98             return this.pcrud.search('acmtcm', {term: term_ids},
99                 flesher);
100         }
101     }
102
103     fetchCoursesForRecord(recordId) {
104         const courseIds = new Set<number>();
105         return this.pcrud.search(
106             'acmcm', {record: recordId}, {atomic: false}
107         ).pipe(tap(material => {
108             courseIds.add(material.course());
109         })).toPromise()
110             .then(() => {
111                 if (courseIds.size) {
112                     return this.getCourses(Array.from(courseIds));
113                 }
114             });
115     }
116
117     // Creating a new acmcm Entry
118     associateMaterials(item, args) {
119         const material = this.idl.create('acmcm');
120         material.item(item.id());
121         if (item.call_number() && item.call_number().record()) {
122             material.record(item.call_number().record());
123         }
124         material.course(args.currentCourse.id());
125         if (args.relationship) { material.relationship(args.relationship); }
126
127         // Apply temporary fields to the item
128         if (args.isModifyingStatus && args.tempStatus) {
129             material.original_status(item.status());
130             item.status(args.tempStatus);
131         }
132         if (args.isModifyingLocation && args.tempLocation) {
133             material.original_location(item.location());
134             item.location(args.tempLocation);
135         }
136         if (args.isModifyingCircMod) {
137             material.original_circ_modifier(item.circ_modifier());
138             item.circ_modifier(args.tempCircMod);
139             if (!args.tempCircMod) { item.circ_modifier(null); }
140         }
141         if (args.isModifyingCallNumber) {
142             material.original_callnumber(item.call_number());
143         }
144         if (args.isModifyingLibrary && args.tempLibrary && this.org.canHaveVolumes(args.tempLibrary)) {
145             material.original_circ_lib(item.circ_lib());
146             item.circ_lib(args.tempLibrary);
147         }
148         const response = {
149             item: item,
150             material: this.pcrud.create(material).toPromise()
151         };
152
153         return response;
154     }
155
156     associateUsers(patron_id, args) {
157         const new_user = this.idl.create('acmcu');
158         if (args.role) { new_user.usr_role(args.role); }
159         new_user.course(args.currentCourse.id());
160         new_user.usr(patron_id);
161         return this.pcrud.create(new_user).toPromise();
162     }
163
164     disassociateMaterials(courses) {
165         const deleteRequest$ = [];
166
167         return new Promise((resolve, reject) => {
168             const course_ids = [];
169             const course_library_hash = {};
170             courses.forEach(course => {
171                 course_ids.push(course.id());
172                 course_library_hash[course.id()] = course.owning_lib();
173             });
174
175             this.pcrud.search('acmcm', {course: course_ids}).subscribe(material => {
176                 deleteRequest$.push(this.net.request(
177                     'open-ils.courses', 'open-ils.courses.detach_material',
178                     this.auth.token(), material.id()));
179             }, (err: unknown) => {
180                 reject(err);
181             }, () => {
182                 merge(...deleteRequest$).subscribe(val => {
183                     console.log(val);
184                 }, (err: unknown) => {
185                     reject(err);
186                 }, () => {
187                     resolve(courses);
188                 });
189             });
190         });
191     }
192
193     detachMaterials(materials) {
194         const deleteRequest$ = [];
195         materials.forEach(material => {
196             deleteRequest$.push(this.net.request(
197                 'open-ils.courses', 'open-ils.courses.detach_material',
198                 this.auth.token(), material.id()));
199         });
200
201         return deleteRequest$;
202     }
203
204     disassociateUsers(user) {
205         return new Promise((resolve, reject) => {
206             const user_ids = [];
207             const course_library_hash = {};
208             user.forEach(course => {
209                 user_ids.push(course.id());
210                 course_library_hash[course.id()] = course.owning_lib();
211             });
212             this.pcrud.search('acmcu', {user: user_ids}).subscribe(u => {
213                 u.course(user_ids);
214                 this.pcrud.autoApply(user).subscribe(res => {
215                     console.debug(res);
216                 }, (err: unknown) => {
217                     reject(err);
218                 }, () => {
219                     resolve(user);
220                 });
221             }, (err: unknown) => {
222                 reject(err);
223             }, () => {
224                 resolve(user_ids);
225             });
226         });
227     }
228
229     removeNonPublicUsers(courseID: Number) {
230         return new Promise((resolve, reject) => {
231             const acmcu_ids = [];
232
233             this.getUsers([courseID]).subscribe(nonPublicUser => {
234                 if(nonPublicUser && nonPublicUser.usr_role().is_public() !== 't') {acmcu_ids.push(nonPublicUser.id());}
235             }, (err: unknown) => {
236                 reject(err);
237             }, () => {
238                 resolve(acmcu_ids);
239                 if (acmcu_ids.length) {
240                     this.pcrud.search('acmcu', {course: courseID, id: acmcu_ids}).subscribe(userToDelete => {
241                         userToDelete.isdeleted(true);
242                         this.pcrud.autoApply(userToDelete).subscribe(val => {
243                             console.debug('deleted: ' + val);
244                         }, (err: unknown) => {
245                             console.log('Error: ' + err);
246                             reject(err);
247                         }, () => {
248                             console.log('Resolving');
249                             resolve(userToDelete);
250                         });
251                     });
252                 }
253             });
254         });
255     }
256
257
258     updateItem(item: IdlObject, courseLib: IdlObject, callNumber: string, updatingVolume: boolean) {
259         const cn = item.call_number();
260
261         const itemObservable = this.pcrud.update(item);
262         const callNumberObservable = this.net.request(
263             'open-ils.cat', 'open-ils.cat.call_number.find_or_create',
264             this.auth.token(), callNumber, cn.record(),
265             cn.owning_lib(), cn.prefix(), cn.suffix(),
266             cn.label_class()
267         ).pipe(switchMap(res => {
268             const event = this.evt.parse(res);
269             if (event) { return throwError(event); }
270             // Not using open-ils.cat.transfer_copies_to_volume,
271             // because we don't necessarily want acp.circ_lib and
272             // acn.owning_lib to match in this scenario
273             item.call_number(res.acn_id);
274             return this.pcrud.update(item);
275         }));
276
277         return updatingVolume ? itemObservable.pipe(switchMap(() => callNumberObservable)).toPromise() :
278             itemObservable.toPromise();
279
280     }
281
282 }