LPXXX Angular Volcopy
authorBill Erickson <berickxx@gmail.com>
Tue, 16 Jun 2020 20:19:55 +0000 (16:19 -0400)
committerBill Erickson <berickxx@gmail.com>
Tue, 16 Jun 2020 20:19:55 +0000 (16:19 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.html
Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.ts
Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.component.ts
Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts

index b7e96d3..a29c3a7 100644 (file)
             </ng-container>
 
             <input type="text" class="form-control form-control-sm"
+              title="{{copyStatLabel(copyNode.target)}}"
               id="barcode-input-{{copyNode.target.id()}}"
               spellcheck="false" [required]="true"
               [ngClass]="{'text-danger': copyNode.target._dupe_barcode}"
index 3f92767..a7975ab 100644 (file)
@@ -119,12 +119,22 @@ export class VolEditComponent implements OnInit {
                 Object.keys(this.bibParts).forEach(bibId => {
                     this.bibParts[bibId] = this.bibParts[bibId]
                     .sort((p1, p2) =>
-                        p1.label_sortkey() < p2.label_sortkey() ? -1 : 1)
+                        p1.label_sortkey() < p2.label_sortkey() ? -1 : 1);
                 });
             }
         );
     }
 
+    copyStatLabel(copy: IdlObject): string {
+        if (copy) {
+            const statId = copy.status();
+            if (statId in this.volcopy.copyStatuses) {
+                return this.volcopy.copyStatuses[statId].name();
+            }
+        }
+        return '';
+    }
+
     recordHasParts(bibId: number): boolean {
         return this.bibParts[bibId] && this.bibParts[bibId].length > 0;
     }
@@ -201,7 +211,7 @@ export class VolEditComponent implements OnInit {
 
             // This will vivify the volNode if needed.
             const vol = this.volcopy.createStubVol(
-                this.context.recordId, orgNode.target.id())
+                this.context.recordId, orgNode.target.id());
 
             vols.push(vol);
 
@@ -231,9 +241,9 @@ export class VolEditComponent implements OnInit {
     addStubCopies(volNode?: HoldingsTreeNode) {
         const nodes = volNode ? [volNode] : this.context.volNodes();
 
-        nodes.forEach(volNode => {
-            if (volNode.children.length == 0) {
-                const vol = volNode.target;
+        nodes.forEach(vNode => {
+            if (vNode.children.length === 0) {
+                const vol = vNode.target;
                 const copy = this.volcopy.createStubCopy(vol);
                 copy.call_number(vol);
                 this.context.findOrCreateCopyNode(copy);
@@ -318,7 +328,7 @@ export class VolEditComponent implements OnInit {
     }
 
     generateBarcodes() {
-               this.autoBarcodeInProgress = true;
+        this.autoBarcodeInProgress = true;
 
         // Autogen only replaces barcodes for items which are in
         // certain statuses.
@@ -332,7 +342,7 @@ export class VolEditComponent implements OnInit {
         if (copies.length > 1) { // seed barcode will always be present
             this.proceedWithAutogen(copies)
             .then(_ => this.autoBarcodeInProgress = false);
-        };
+        }
     }
 
     proceedWithAutogen(copyList: IdlObject[]): Promise<any> {
@@ -361,7 +371,7 @@ export class VolEditComponent implements OnInit {
         })).toPromise();
     }
 
-       barcodeChanged(copy: IdlObject, barcode: string) {
+    barcodeChanged(copy: IdlObject, barcode: string) {
         copy.barcode(barcode);
         copy.ischanged(true);
         copy._dupe_barcode = false;
index f71f6da..0f34de4 100644 (file)
@@ -18,7 +18,7 @@ const COPY_FLESH = {
     flesh_fields: {
         acp: ['call_number', 'location', 'parts']
     }
-}
+};
 
 interface EditSession {
 
@@ -84,7 +84,9 @@ export class VolCopyComponent implements OnInit {
         this.loading = true;
         this.context.reset();
 
-        this.fetchHoldings(copyIds)
+        this.volcopy.fetchDefaults()
+        .then(_ => this.volcopy.fetchCopyStats())
+        .then(_ => this.fetchHoldings(copyIds))
         .then(_ => this.volcopy.applyVolLabels(
             this.context.volNodes().map(n => n.target)))
         .then(_ => this.holdings.fetchCallNumberClasses())
@@ -201,7 +203,7 @@ export class VolCopyComponent implements OnInit {
         const copies = [];
         vols.forEach(vol => {
             const volData = volDataList.filter(
-                volData => volData.callnumber === vol.id())[0];
+                vData => vData.callnumber === vol.id())[0];
 
             const copy =
                 this.volcopy.createStubCopy(vol, {circLib: volData.owner});
@@ -241,7 +243,7 @@ export class VolCopyComponent implements OnInit {
         return this.pcrud.search('acn',
             {record: ids, deleted: 'f', label: {'!=' : '##URI##'}},
             {}, {idlist: true, atomic: true}
-        ).toPromise().then(volIds =>this.fetchVols(volIds));
+        ).toPromise().then(volIds => this.fetchVols(volIds));
     }
 
 
@@ -304,7 +306,7 @@ export class VolCopyComponent implements OnInit {
             }
 
             volumes.push(vol);
-        })
+        });
 
         if (volumes.length > 0) {
             this.saveApi(volumes);
index 8bde618..73d8654 100644 (file)
@@ -9,6 +9,7 @@ import {EventService, EgEvent} from '@eg/core/event.service';
 import {AuthService} from '@eg/core/auth.service';
 import {VolCopyContext} from './volcopy';
 import {HoldingsService, CallNumData} from '@eg/staff/share/holdings/holdings.service';
+import {ServerStoreService} from '@eg/core/server-store.service';
 
 /* Managing volcopy data */
 
@@ -17,25 +18,53 @@ export class VolCopyService {
 
     autoId = -1;
 
+    defaultValues: any = null;
+    copyStatuses: {[id: number]: IdlObject} = null;
+
     constructor(
         private evt: EventService,
         private net: NetService,
         private idl: IdlService,
         private org: OrgService,
         private auth: AuthService,
-        private holdings: HoldingsService
+        private pcrud: PcrudService,
+        private holdings: HoldingsService,
+        private store: ServerStoreService
     ) {}
 
+    fetchDefaults(): Promise<any> {
+        if (this.defaultValues) { return Promise.resolve(); }
+
+        return this.store.getItem('cat.copy.defaults').then(
+            defaults => {
+                this.defaultValues = defaults || {};
+            }
+        );
+    }
+
+    fetchCopyStats(): Promise<any> {
+        if (this.copyStatuses) { return Promise.resolve(); }
+        this.copyStatuses = {};
 
-    // Fetch vol labels for a single record
+        return this.pcrud.retrieveAll('ccs').pipe(tap(stat =>
+            this.copyStatuses[stat.id()] = stat
+        )).toPromise();
+    }
+
+    // Fetch vol labels for a single record based on the defeault
+    // classification scheme
     fetchRecordVolLabels(id: number): Promise<string[]> {
         if (!id) { return Promise.resolve([]); }
 
         // NOTE: see https://bugs.launchpad.net/evergreen/+bug/1874897
         // for more on MARC call numbers and classification scheme.
+        // If there is no workstation-default value, pass null
+        // to use the org unit default.
+
         return this.net.request(
             'open-ils.cat',
-            'open-ils.cat.biblio.record.marc_cn.retrieve', id
+            'open-ils.cat.biblio.record.marc_cn.retrieve',
+            id, this.defaultValues.classification || null
         ).toPromise().then(res => {
             return Object.values(res)
                 .map(blob => Object.values(blob)[0]).sort();
@@ -51,9 +80,8 @@ export class VolCopyService {
         vol.record(recordId);
         vol.label(null);
         vol.owning_lib(Number(orgId));
-
-        vol.prefix(options.prefix || -1);
-        vol.suffix(options.suffix || -1);
+        vol.prefix(this.defaultValues.prefix || -1);
+        vol.suffix(this.defaultValues.suffix || -1);
 
         return vol;
     }
@@ -79,8 +107,6 @@ export class VolCopyService {
         copy.mint_condition('t');
         copy.parts([]);
 
-        // TODO: defaults?
-
         return copy;
     }
 
@@ -89,40 +115,61 @@ export class VolCopyService {
     // applying labels to vols that need it.
     setVolClassLabels(vols: IdlObject[]): Promise<any> {
 
+        return this.applyVolClasses(vols)
+        .then(_ => this.applyVolLabels(vols));
+    }
+
+    // Apply label_class values to any vols that need it based either on
+    // the workstation default value or the org setting for the
+    // owning lib library.
+    applyVolClasses(vols: IdlObject[]): Promise<any> {
+
+        vols = vols.filter(v => !v.label_class());
+
         const orgIds: any = {};
         vols.forEach(vol => orgIds[vol.owning_lib()] = true);
 
-        // Serialize
-        let promise = Promise.resolve();
+        let promise = Promise.resolve(); // Serialization
 
-        // TODO: if there is a local default value (ws setting?)
-        // apply it here and bypass the network call.
+        if (this.defaultValues.classification) {
+            // Workstation default classification overrides the
+            // classification that might be used at the owning lib.
 
-        const volsWantLabels = [];
-        Object.keys(orgIds).map(orgId => Number(orgId)).forEach(orgId => {
-            promise = promise.then(_ => {
+            vols.forEach(vol =>
+                vol.label_class(this.defaultValues.classification));
 
-                return this.org.settings(
-                    'cat.default_classification_scheme', orgId)
-                .then(sets => {
+            return promise;
 
-                    const orgVols = vols.filter(v => v.owning_lib() === orgId);
-                    orgVols.forEach(vol => {
-                        vol.label_class(
-                            sets['cat.default_classification_scheme'] || 1
-                        );
-                        if (!vol.label()) { volsWantLabels.push(vol); }
+        } else {
+
+            // Get the label class default for each owning lib and
+            // apply to the volumes owned by that lib.
+
+            Object.keys(orgIds).map(orgId => Number(orgId))
+            .forEach(orgId => {
+                promise = promise.then(_ => {
+
+                    return this.org.settings(
+                        'cat.default_classification_scheme', orgId)
+                    .then(sets => {
+
+                        const orgVols = vols.filter(v => v.owning_lib() === orgId);
+                        orgVols.forEach(vol => {
+                            vol.label_class(
+                                sets['cat.default_classification_scheme'] || 1
+                            );
+                        });
                     });
                 });
             });
-        });
-
-        return promise.then(_ => this.applyVolLabels(volsWantLabels));
+        }
     }
 
     // Apply labels to volumes based on the appropriate MARC call number.
     applyVolLabels(vols: IdlObject[]): Promise<any> {
 
+        vols = vols.filter(v => !v.label());
+
         // Serialize
         let promise = Promise.resolve();
 
@@ -174,25 +221,33 @@ export class VolCopyService {
 
         const setting = fastAdd ?
             'cat.default_copy_status_fast' :
-            'cat.default_copy_status_normal'
+            'cat.default_copy_status_normal';
 
-        const orgIds: any = {};
-        copies.forEach(copy => orgIds[copy.circ_lib()] = true);
+        let promise = Promise.resolve(); // Seralize
 
-        let promise = Promise.resolve();
-        Object.keys(orgIds).forEach(orgId => {
+        copies.forEach(copy => {
+
+            // Avoid unnecessary lookups.  Copy may have been modified
+            // during a previous iteration of this loop.
+            if (!isNaN(copy.status())) { return; }
 
             promise = promise.then(_ =>
-                this.org.settings(setting, Number(orgId))
+                this.org.settings(setting, copy.circ_lib())
+
             ).then(sets => {
+
                 // 0 == Available; 5 == In Process
                 const stat = sets[setting] || (fastAdd ? 0 : 5);
-                const orgCopies =
-                    copies.filter(copy => copy.circ_lib() === orgId);
-                orgCopies.forEach(copy => copy.status(stat));
+
+                copies.forEach(copy2 => {
+                    if (copy2.circ_lib() === copy.circ_lib()) {
+                        copy2.status(stat);
+                    }
+                });
             });
         });
 
         return promise;
     }
 }
+