Disassociate when Deleting a Course.
authorKyle Huckins <khuckins@catalyte.io>
Wed, 20 Nov 2019 21:41:59 +0000 (21:41 +0000)
committerJane Sandberg <sandbej@linnbenton.edu>
Mon, 7 Sep 2020 18:11:25 +0000 (11:11 -0700)
- Move disassociation code into Course Service.
- Automatically disassociate items and return them
to their original state when deleting a course.

Signed-off-by: Kyle Huckins <khuckins@catalyte.io>
 Changes to be committed:
modified:   Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course-associate-material.component.ts
modified:   Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course-list.component.ts
modified:   Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course-reserves.module.ts
new file:   Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course.service.ts
modified:   Open-ILS/src/sql/Pg/040.schema.asset.sql

Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course-associate-material.component.ts
Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course-list.component.ts
Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course-reserves.module.ts
Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course.service.ts [new file with mode: 0644]
Open-ILS/src/sql/Pg/040.schema.asset.sql

index cd40056..cb8eeeb 100644 (file)
@@ -13,6 +13,7 @@ import {GridComponent} from '@eg/share/grid/grid.component';
 import {IdlObject, IdlService} from '@eg/core/idl.service';
 import {StringComponent} from '@eg/share/string/string.component';
 import {ToastService} from '@eg/share/toast/toast.service';
+import {CourseService} from './course.service';
 
 @Component({
     selector: 'eg-course-associate-material-dialog',
@@ -50,7 +51,8 @@ export class CourseAssociateMaterialComponent extends DialogComponent {
         private org: OrgService,
         private evt: EventService,
         private modal: NgbModal,
-        private toast: ToastService
+        private toast: ToastService,
+        private courseSvc: CourseService
     ) {
         super(modal);
         this.gridDataSource = new GridDataSource();
@@ -72,7 +74,7 @@ export class CourseAssociateMaterialComponent extends DialogComponent {
             material.isdeleted(true);
             this.pcrud.autoApply(material).subscribe(
                 val => {
-                    this.resetItemFields(material);
+                    this.courseSvc.resetItemFields(material, this.currentCourse.owning_lib());
                     console.debug('deleted: ' + val);
                     this.deleteSuccessString.current().then(str => this.toast.success(str));
                 },
@@ -84,28 +86,6 @@ export class CourseAssociateMaterialComponent extends DialogComponent {
         });
     }
 
-    resetItemFields(material) {
-        this.pcrud.retrieve('acp', material.item(),
-            {flesh: 3, flesh_fields: {acp: ['call_number']}}).subscribe(copy => {
-            if (material.original_status()) {
-                copy.status(material.original_status());
-            }
-            if (copy.circ_modifier() != material.original_circ_modifier()) {
-                copy.circ_modifier(material.original_circ_modifier());
-            }
-            if (material.original_location()) {
-                copy.location(material.original_location());
-            }
-            if (material.original_callnumber()) {
-                this.pcrud.retrieve('acn', material.original_callnumber()).subscribe(cn => {
-                    this.updateItem(copy, cn.label(), true);
-                });
-            } else {
-                this.updateItem(copy, copy.call_number().label(), false);
-            }
-        });
-    }
-
     associateItem(barcode, relationship) {
         if (barcode) {
             this.pcrud.search('acp', {barcode: barcode},
@@ -135,13 +115,14 @@ export class CourseAssociateMaterialComponent extends DialogComponent {
                    console.debug('created: ' + val);
                    let new_cn = item.call_number().label();
                    if (this.tempCallNumber) new_cn = this.tempCallNumber;
-                    this.updateItem(item, new_cn, this.isModifyingCallNumber);
-                    if (item.circ_lib() != this.currentCourse.owning_lib()) {
-                        this.differentLibraryString.current().then(str => this.toast.warning(str));
-                    } else {
-                        this.successString.current().then(str => this.toast.success(str));
-                    }
-                    this.fetchItem(item.id(), relationship);
+                    this.courseSvc.updateItem(item, this.currentCourse.owning_lib(), new_cn, this.isModifyingCallNumber).then(res => {
+                        this.fetchItem(item.id(), relationship);                        
+                        if (item.circ_lib() != this.currentCourse.owning_lib()) {
+                            this.differentLibraryString.current().then(str => this.toast.warning(str));
+                        } else {
+                            this.successString.current().then(str => this.toast.success(str));
+                        }
+                    });
 
                     // Cleaning up inputs
                     this.barcodeInput = "";
@@ -161,41 +142,6 @@ export class CourseAssociateMaterialComponent extends DialogComponent {
         }
     }
 
-    updateItem(item: IdlObject, call_number, updatingVolume) {
-        return new Promise((resolve, reject) => {
-            this.pcrud.update(item).subscribe(item_id => {
-                if (updatingVolume) {
-                    let cn = item.call_number();
-                    return this.net.request(
-                        'open-ils.cat', 'open-ils.cat.call_number.find_or_create',
-                        this.auth.token(), call_number, cn.record(),
-                        this.currentCourse.owning_lib(), cn.prefix(), cn.suffix(),
-                        cn.label_class()
-                    ).subscribe(res => {
-                        let event = this.evt.parse(res);
-                        if (event) return;
-                        return this.net.request(
-                            'open-ils.cat', 'open-ils.cat.transfer_copies_to_volume',
-                            this.auth.token(), res.acn_id, [item.id()]
-                        ).subscribe(transfered_res => {
-                            console.debug("Copy transferred to volume with code " + transfered_res);
-                        }, err => {
-                            reject(err);
-                        }, () => {
-                            resolve(item);
-                        });
-                    }, err => {
-                        reject(err);
-                    }, () => {
-                        resolve(item);
-                    });
-                } else {
-                    return this.pcrud.update(item);
-                }
-            });
-        });
-    }
-
     fetchMaterials(pager: Pager): Observable<any> {
         return new Observable<any>(observer => {
             this.materials.forEach(material => {
index e806539..ea5dc2f 100644 (file)
@@ -2,6 +2,7 @@ import {Component, Input, ViewChild, OnInit} from '@angular/core';
 import {IdlObject} from '@eg/core/idl.service';
 import {PcrudService} from '@eg/core/pcrud.service';
 import {AuthService} from '@eg/core/auth.service';
+import {CourseService} from './course.service';
 import {NetService} from '@eg/core/net.service';
 import {OrgService} from '@eg/core/org.service';
 import {GridComponent} from '@eg/share/grid/grid.component';
@@ -39,11 +40,12 @@ export class CourseListComponent implements OnInit {
     search_value = '';
 
     constructor(
-            private auth: AuthService,
-            private net: NetService,
-            private org: OrgService,
-            private pcrud: PcrudService,
-            private toast: ToastService,
+        private auth: AuthService,
+        private courseSvc: CourseService,
+        private net: NetService,
+        private org: OrgService,
+        private pcrud: PcrudService,
+        private toast: ToastService,
     ){}
 
     ngOnInit() {
@@ -122,7 +124,11 @@ export class CourseListComponent implements OnInit {
     }
 
     deleteSelected(idl_object: IdlObject[]) {
-            idl_object.forEach(idl_object => idl_object.isdeleted(true));
+        this.courseSvc.disassociateMaterials(idl_object).then(res => {
+            console.log(res);
+            idl_object.forEach(idl_object => {
+                idl_object.isdeleted(true)
+            });
             this.pcrud.autoApply(idl_object).subscribe(
                 val => {
                     console.debug('deleted: ' + val);
@@ -133,9 +139,10 @@ export class CourseListComponent implements OnInit {
                     this.deleteFailedString.current()
                         .then(str => this.toast.danger(str));
                 },
-                ()  => this.grid.reload()
+                () => this.grid.reload()
             );
-        };
+        });
+    };
 
     fetchCourseMaterials(course, currentMaterials): Promise<any> {
         return new Promise((resolve, reject) => {
index c87331b..6f6eed5 100644 (file)
@@ -5,7 +5,7 @@ import {CourseListComponent} from './course-list.component';
 import {CourseAssociateMaterialComponent} from './course-associate-material.component';
 import {CourseReservesRoutingModule} from './routing.module';
 import {ItemLocationSelectModule} from '@eg/share/item-location-select/item-location-select.module';
-
+import {CourseService} from './course.service'
 @NgModule({
   declarations: [
     CourseListComponent,
@@ -20,6 +20,7 @@ import {ItemLocationSelectModule} from '@eg/share/item-location-select/item-loca
   exports: [
   ],
   providers: [
+    CourseService
   ]
 })
 
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course.service.ts b/Open-ILS/src/eg2/src/app/staff/admin/server/course-reserves/course.service.ts
new file mode 100644 (file)
index 0000000..c8b60cc
--- /dev/null
@@ -0,0 +1,100 @@
+import {AuthService} from '@eg/core/auth.service';
+import {EventService} from '@eg/core/event.service';
+import {IdlObject, IdlService} from '@eg/core/idl.service';
+import {NetService} from '@eg/core/net.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+
+export class CourseService {
+
+    constructor(
+        private auth: AuthService,
+        private evt: EventService,
+        private idl: IdlService,
+        private net: NetService,
+        private pcrud: PcrudService
+    ) {}
+
+    disassociateMaterials(courses) {
+        return new Promise((resolve, reject) => {
+            let course_ids = [];
+            let course_library_hash = {};
+            courses.forEach(course => {
+                course_ids.push(course.id());
+                course_library_hash[course.id()] = course.owning_lib();
+            });
+            this.pcrud.search('acmcm', {course: course_ids}).subscribe(material => {
+                material.isdeleted(true);
+                this.resetItemFields(material, course_library_hash[material.course()]);
+                this.pcrud.autoApply(material).subscribe(res => {
+                    console.log(res);
+                }, err => {
+                    reject(err);
+                }, () => {
+                    resolve(material);
+                });
+            }, err => {
+                reject(err)
+            }, () => {
+                resolve(courses);
+            });
+        });
+    }
+
+    resetItemFields(material, course_lib) {
+        this.pcrud.retrieve('acp', material.item(),
+            {flesh: 3, flesh_fields: {acp: ['call_number']}}).subscribe(copy => {
+            if (material.original_status()) {
+                copy.status(material.original_status());
+            }
+            if (copy.circ_modifier() != material.original_circ_modifier()) {
+                copy.circ_modifier(material.original_circ_modifier());
+            }
+            if (material.original_location()) {
+                copy.location(material.original_location());
+            }
+            if (material.original_callnumber()) {
+                this.pcrud.retrieve('acn', material.original_callnumber()).subscribe(cn => {
+                    this.updateItem(copy, course_lib, cn.label(), true);
+                });
+            } else {
+                this.updateItem(copy, course_lib, copy.call_number().label(), false);
+            }
+        });
+    }
+
+    updateItem(item: IdlObject, course_lib, call_number, updatingVolume) {
+        return new Promise((resolve, reject) => {
+            this.pcrud.update(item).subscribe(item_id => {
+                if (updatingVolume) {
+                    let cn = item.call_number();
+                    return this.net.request(
+                        'open-ils.cat', 'open-ils.cat.call_number.find_or_create',
+                        this.auth.token(), call_number, cn.record(),
+                        course_lib, cn.prefix(), cn.suffix(),
+                        cn.label_class()
+                    ).subscribe(res => {
+                        let event = this.evt.parse(res);
+                        if (event) return;
+                        return this.net.request(
+                            'open-ils.cat', 'open-ils.cat.transfer_copies_to_volume',
+                            this.auth.token(), res.acn_id, [item.id()]
+                        ).subscribe(transfered_res => {
+                            console.debug("Copy transferred to volume with code " + transfered_res);
+                        }, err => {
+                            reject(err);
+                        }, () => {
+                            resolve(item);
+                        });
+                    }, err => {
+                        reject(err);
+                    }, () => {
+                        resolve(item);
+                    });
+                } else {
+                    return this.pcrud.update(item);
+                }
+            });
+        });
+    }
+
+}
\ No newline at end of file
index 2d21799..2091a69 100644 (file)
@@ -1124,7 +1124,11 @@ CREATE TABLE asset.course_module_course_materials (
     id              SERIAL PRIMARY KEY,
     course          INT NOT NULL REFERENCES asset.course_module_course (id),
     item            INT NOT NULL REFERENCES asset.copy (id),
-    relationship    TEXT
+    relationship    TEXT,
+    original_location      INT REFERENCES asset.copy_location,
+    original_status        INT REFERENCES config.copy_status,
+    original_circ_modifier INT REFERENCES config.circ_modifier,
+    original_callnumber    INT REFERENCES asset.call_number
 );
 
 CREATE TABLE asset.course_module_non_cat_course_materials (