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