LPXXX Angular Volcopy
authorBill Erickson <berickxx@gmail.com>
Mon, 29 Jun 2020 21:51:32 +0000 (17:51 -0400)
committerBill Erickson <berickxx@gmail.com>
Mon, 29 Jun 2020 21:51:32 +0000 (17:51 -0400)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/cat/volcopy/config.component.html
Open-ILS/src/eg2/src/app/staff/cat/volcopy/copy-attrs.component.html
Open-ILS/src/eg2/src/app/staff/cat/volcopy/copy-attrs.component.ts
Open-ILS/src/eg2/src/app/staff/cat/volcopy/vol-edit.component.html
Open-ILS/src/eg2/src/app/staff/cat/volcopy/volcopy.service.ts
Open-ILS/src/eg2/src/app/staff/share/holdings/holdings.service.ts

index 00fbe36..d3793ab 100644 (file)
@@ -64,7 +64,7 @@
                     [selectedId]="volcopy.defaults.values.classification || 1"
                     [smallFormControl]="true"
                     (onChange)="volcopy.defaults.values.classification = $event ? $event.id : null">
-                    <eg-combobox-entry *ngFor="let cls of volcopy.volClasses"
+                    <eg-combobox-entry *ngFor="let cls of volcopy.commonData.acn_class"
                       [entryId]="cls.id()" [entryLabel]="cls.name()">
                     </eg-combobox-entry>
                   </eg-combobox>
@@ -85,7 +85,7 @@
                     <eg-combobox-entry 
                       entryLabel="<None>" i18n-entryLabel [entryId]="-1">
                     </eg-combobox-entry>
-                    <eg-combobox-entry *ngFor="let pfx of volcopy.volPrefixes"
+                    <eg-combobox-entry *ngFor="let pfx of volcopy.commonData.acn_prefix"
                       [entryId]="pfx.id()" [entryLabel]="pfx.label()">
                     </eg-combobox-entry>
                   </eg-combobox>
                     <eg-combobox-entry 
                       entryLabel="<None>" i18n-entryLabel [entryId]="-1">
                     </eg-combobox-entry>
-                    <eg-combobox-entry *ngFor="let sfx of volcopy.volSuffixes"
+                    <eg-combobox-entry *ngFor="let sfx of volcopy.commonData.acn_suffix"
                       [entryId]="sfx.id()" [entryLabel]="sfx.label()">
                     </eg-combobox-entry>
                   </eg-combobox>
index e20dcac..4245d1e 100644 (file)
@@ -72,6 +72,7 @@
   <div class="flex-1 p-1">
     <div class="p-1"><h4 class="font-weight-bold" i18n>Identification</h4></div>
 
+    <!-- TODO: status is batch editable under certain conditions -->
     <div class="mb-1" *ngIf="displayAttr('status')">
       <eg-batch-item-attr label="Status" i18n-label [readOnly]="true"
         [labelCounts]="itemAttrCounts('status')">
         <eg-combobox domId="age_protect-input"
           (ngModelChange)="values['age_protect'] = $event ? $event.id : null"
           [ngModel]="values['age_protect']">
-          <eg-combobox-entry *ngFor="let rule of volcopy.ageProtectRules"
+          <eg-combobox-entry 
+            *ngFor="let rule of volcopy.commonData.acp_age_protect"
             [entryId]="rule.id()" [entryLabel]="rule.name()">
           </eg-combobox-entry>
         </eg-combobox>
         <eg-combobox domId="floating-input"
           (ngModelChange)="values['floating'] = $event ? $event.id : null"
           [ngModel]="values['floating']">
-          <eg-combobox-entry *ngFor="let grp of volcopy.floatingGroups"
+          <eg-combobox-entry 
+            *ngFor="let grp of volcopy.commonData.acp_floating_group"
             [entryId]="grp.id()" [entryLabel]="grp.name()">
           </eg-combobox-entry>
         </eg-combobox>
         <eg-combobox domId="circ-as-type-input"
           (ngModelChange)="values['circ_as_type'] = $event ? $event.id : null"
           [ngModel]="values['circ_as_type']">
-          <eg-combobox-entry *ngFor="let map of volcopy.itemTypeMaps"
+          <eg-combobox-entry *ngFor="let map of volcopy.commonData.acp_item_type_map"
             [entryId]="map.code()" [entryLabel]="map.value()">
           </eg-combobox-entry>
         </eg-combobox>
       <ng-template #circModifierTemplate>
         <select class="form-control" [(ngModel)]="values['circ_modifier']">
           <option [value]="null" i18n>&lt;Unset&gt;</option>
-          <option *ngFor="let mod of circModifiers"
+          <option *ngFor="let mod of volcopy.commonData.circ_modifier"
             value="{{mod.code()}}">{{mod.name()}}</option>
         </select>
       </ng-template>
index bad44c6..e520736 100644 (file)
@@ -110,7 +110,7 @@ export class CopyAttrsComponent implements OnInit, AfterViewInit {
     }
 
     statCats(): IdlObject[] {
-        return this.volcopy.statCats;
+        return this.volcopy.commonData.acp_stat_cat;
     }
 
 
@@ -196,12 +196,12 @@ export class CopyAttrsComponent implements OnInit, AfterViewInit {
                 return this.org.get(value).shortname();
 
             case 'age_protect':
-                const rule = this.volcopy.ageProtectRules.filter(
+                const rule = this.volcopy.commonData.acp_age_protect.filter(
                     r => r.id() === Number(value))[0];
                 return rule ? rule.name() : '';
 
             case 'floating':
-                const grp = this.volcopy.floatingGroups.filter(
+                const grp = this.volcopy.commonData.acp_floating_group.filter(
                     g => g.id() === Number(value))[0];
                 return grp ? grp.name() : '';
 
@@ -212,12 +212,12 @@ export class CopyAttrsComponent implements OnInit, AfterViewInit {
                 return this.fineLevelLabelMap[value];
 
             case 'circ_as_type':
-                const map = this.volcopy.itemTypeMaps.filter(
+                const map = this.volcopy.commonData.acp_item_type_map.filter(
                     m => m.code() === value)[0];
                 return map ? map.value() : '';
 
             case 'circ_modifier':
-                const mod = this.volcopy.circModifiers.filter(
+                const mod = this.volcopy.commonData.circ_modifier.filter(
                     m => m.code() === value)[0];
                 return mod ? mod.name() : '';
 
index 86e6cf7..8aa5deb 100644 (file)
@@ -19,7 +19,7 @@
     <div><label class="font-weight-bold" i18n>Classification</label></div>
     <div>
       <eg-combobox [smallFormControl]="true" [(ngModel)]="batchVolClass">
-        <eg-combobox-entry *ngFor="let cls of volcopy.volClasses"
+        <eg-combobox-entry *ngFor="let cls of volcopy.commonData.acn_class"
           [entryId]="cls.id()" [entryLabel]="cls.name()">
         </eg-combobox-entry>
       </eg-combobox>
@@ -29,7 +29,7 @@
     <div><label class="font-weight-bold" i18n>Prefix</label></div>
     <div>
       <eg-combobox [smallFormControl]="true" [(ngModel)]="batchVolPrefix">
-        <eg-combobox-entry *ngFor="let pfx of volcopy.volPrefixes"
+        <eg-combobox-entry *ngFor="let pfx of volcopy.commonData.acn_prefix"
           [entryId]="pfx.id()" [entryLabel]="pfx.label()">
         </eg-combobox-entry>
       </eg-combobox>
@@ -48,7 +48,7 @@
     <div><label class="font-weight-bold" i18n>Suffix</label></div>
     <div>
       <eg-combobox [smallFormControl]="true" [(ngModel)]="batchVolSuffix">
-        <eg-combobox-entry *ngFor="let sfx of volcopy.volSuffixes"
+        <eg-combobox-entry *ngFor="let sfx of volcopy.commonData.acn_suffix"
           [entryId]="sfx.id()" [entryLabel]="sfx.label()">
         </eg-combobox-entry>
       </eg-combobox>
               [smallFormControl]="true"
               [required]="true"
               (onChange)="applyVolValue(volNode.target, 'label_class', $event ? $event.id : null)">
-              <eg-combobox-entry *ngFor="let cls of volcopy.volClasses"
+              <eg-combobox-entry *ngFor="let cls of volcopy.commonData.acn_class"
                 [entryId]="cls.id()" [entryLabel]="cls.name()">
               </eg-combobox-entry>
             </eg-combobox>
               <eg-combobox-entry
                 [entryId]="-1" entryLabel="<None>" i18n-entryLabel>
               </eg-combobox-entry>
-              <eg-combobox-entry *ngFor="let pfx of volcopy.volPrefixes"
+              <eg-combobox-entry *ngFor="let pfx of volcopy.commonData.acn_prefix"
                 [entryId]="pfx.id()" [entryLabel]="pfx.label()">
               </eg-combobox-entry>
             </eg-combobox>
               <eg-combobox-entry
                 [entryId]="-1" entryLabel="<None>" i18n-entryLabel>
               </eg-combobox-entry>
-              <eg-combobox-entry *ngFor="let sfx of volcopy.volSuffixes"
+              <eg-combobox-entry *ngFor="let sfx of volcopy.commonData.acn_suffix"
                 [entryId]="sfx.id()" [entryLabel]="sfx.label()">
               </eg-combobox-entry>
             </eg-combobox>
index 80f04c4..446acc7 100644 (file)
@@ -29,8 +29,7 @@ export class VolCopyService {
 
     localOrgs: number[];
     defaults: VolCopyDefaults = null;
-    defaultLocation: IdlObject;
-    copyStatuses: {[id: number]: IdlObject} = null;
+    copyStatuses: {[id: number]: IdlObject} = {};
     bibParts: {[bibId: number]: IdlObject[]} = {};
 
     // This will be all 'local' copy locations plus any remote
@@ -40,19 +39,13 @@ export class VolCopyService {
     // Track this here so it can survive route changes.
     currentContext: VolCopyContext;
 
-    ageProtectRules: IdlObject[] = [];
-    floatingGroups: IdlObject[] = [];
-    itemTypeMaps: IdlObject[] = [];
-    circModifiers: IdlObject[] = [];
-    statCats: IdlObject[] = [];
     statCatEntryMap: {[id: number]: IdlObject} = {}; // entry id => entry
-    volClasses: IdlObject[] = null;
-    volPrefixes: IdlObject[] = null;
-    volSuffixes: IdlObject[] = null;
 
     templateNames: ComboboxEntry[] = [];
     templates: any = {};
 
+    commonData: {[key: string]: IdlObject[]} = {};
+
     constructor(
         private evt: EventService,
         private net: NetService,
@@ -69,100 +62,42 @@ export class VolCopyService {
     // Fetch the data that is always needed.
     load(): Promise<any> {
 
-        if (this.itemTypeMaps.length > 0) { return Promise.resolve(); }
+        if (this.commonData.acp_item_type_map) { return Promise.resolve(); }
 
         this.localOrgs = this.org.fullPath(this.auth.user().ws_ou(), true);
 
-        return this.fetchDefaults()
-        .then(_ => this.getLocations())
-        .then(_ => this.holdings.fetchCallNumberClasses())
-        .then(cls => this.volClasses = cls)
-
-        .then(_ => {
-            return this.holdings.fetchCallNumberPrefixes().then(prefixes =>
-                this.volPrefixes = prefixes
-                    .filter(sfx => sfx.id() !== -1)
-                    .filter(pfx => this.localOrgs.includes(pfx.owning_lib()))
-            );
-        })
-
-        .then(_ => {
-            return this.holdings.fetchCallNumberSuffixes().then(suffixes =>
-                this.volSuffixes = suffixes
-                    .filter(sfx => sfx.id() !== -1)
-                    .filter(sfx => this.localOrgs.includes(sfx.owning_lib()))
-            );
-        })
-
-        .then(_ => this.fetchCopyStats())
-        .then(_ => this.fetchTemplates())
-        .then(_ => {
-
-            return this.pcrud.retrieveAll('crahp')
-            .pipe(tap(rule => this.ageProtectRules.push(rule))).toPromise()
-
-        }).then(_ => {
-
-            this.ageProtectRules = this.ageProtectRules.sort(
-                (a, b) => a.name() < b.name() ? -1 : 1);
-
-        }).then(_ => {
-
-            return this.pcrud.retrieveAll('cfg')
-            .pipe(tap(rule => this.floatingGroups.push(rule))).toPromise();
-
-        }).then(_ => {
-
-            this.floatingGroups = this.floatingGroups.sort(
-                (a, b) => a.name() < b.name() ? -1 : 1);
-
-        }).then(_ => {
-
-            return this.pcrud.retrieveAll('ccm')
-            .pipe(tap(rule => this.circModifiers.push(rule))).toPromise();
-
-        }).then(_ => {
-
-            this.circModifiers = this.circModifiers.sort(
-                (a, b) => a.name() < b.name() ? -1 : 1);
-
-        }).then(_ => {
-
-            return this.pcrud.retrieveAll('citm')
-            .pipe(tap(itemType => this.itemTypeMaps.push(itemType))).toPromise();
+        return this.net.request(
+            'open-ils.cat', 'open-ils.cat.volcopy.data', this.auth.token()
+        ).pipe(tap(dataset => {
+            const key = Object.keys(dataset)[0];
+            this.commonData[key] = dataset[key];
+        })).toPromise()
+        .then(_ => this.ingestCommonData())
+        .then(_ => this.fetchDefaults())
+        .then(_ => this.fetchTemplates());
+    }
 
-        }).then(_ => {
 
-            this.itemTypeMaps = this.itemTypeMaps.sort(
-                (a, b) => a.value() < b.value() ? -1 : 1);
+    ingestCommonData() {
 
-        }).then(_ => {
+        this.commonData.acp_location.forEach(
+            loc => this.copyLocationMap[loc.id()] = loc);
 
-            return this.net.request('open-ils.circ',
-                'open-ils.circ.stat_cat.asset.retrieve.all',
-                this.auth.token(), this.auth.user().ws_ou()
-            ).toPromise().then(stats => this.statCats = stats);
 
-        }).then(_ => {
+        // Remove the -1 prefix and suffix so they can be treated
+        // specially in the markup.
+        this.commonData.acn_prefix =
+            this.commonData.acn_prefix.filter(pfx => pfx.id() !== -1);
 
-            // Sort most local to the front of the list.
-            this.statCats = this.statCats.sort((s1, s2) => {
-                const d1 = this.org.get(s1.owner()).ou_type().depth();
-                const d2 = this.org.get(s2.owner()).ou_type().depth();
+        this.commonData.acn_suffix =
+            this.commonData.acn_suffix.filter(sfx => sfx.id() !== -1);
 
-                if (d1 > d2) {
-                    return -1;
-                } else if (d1 < d2) {
-                    return 1;
-                } else {
-                    return s1.name() < s2.name() ? -1 : 1;
-                }
-            });
+        this.commonData.acp_status.forEach(
+            stat => this.copyStatuses[stat.id()] = stat);
 
-            this.statCats.forEach(cat => {
-                cat.entries().forEach(
-                    entry => this.statCatEntryMap[entry.id()] = entry);
-            });
+        this.commonData.acp_stat_cat.forEach(cat => {
+            cat.entries().forEach(
+                entry => this.statCatEntryMap[entry.id()] = entry);
         });
     }
 
@@ -176,16 +111,6 @@ export class VolCopyService {
             .toPromise();
     }
 
-    getLocations(): Promise<any> {
-        this.localOrgs = this.org.fullPath(this.auth.user().ws_ou(), true);
-
-        return this.pcrud.search('acpl',
-            {deleted: 'f', owning_lib: this.localOrgs},
-            {order_by: {acpl: 'name'}}
-        ).pipe(tap(loc => this.copyLocationMap[loc.id()] = loc)
-        ).toPromise();
-    }
-
     fetchTemplates(): Promise<any> {
 
         // First check for local copy templates, since server-side
@@ -224,27 +149,7 @@ export class VolCopyService {
             (defaults: VolCopyDefaults) => {
                 this.defaults = defaults || {values: {}, hidden: {}};
             }
-
-        ).then(_ => {
-
-            // Use the first non-deleted copy location within org unit
-            // range as the default.  Typically "Stacks".
-
-            this.localOrgs = this.org.fullPath(this.auth.user().ws_ou(), true);
-            return this.pcrud.search('acpl',
-                {deleted: 'f', owning_lib: this.localOrgs},
-                {order_by: {acpl: 'id'}, limit: 1}
-            ).toPromise().then(loc => this.defaultLocation = loc);
-        });
-    }
-
-    fetchCopyStats(): Promise<any> {
-        if (this.copyStatuses) { return Promise.resolve(); }
-        this.copyStatuses = {};
-
-        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
@@ -295,7 +200,7 @@ export class VolCopyService {
         copy.deposit_amount(0);
         copy.fine_level(2);     // Normal
         copy.loan_duration(2);  // Normal
-        copy.location(this.defaultLocation);  // Stacks / fleshed
+        copy.location(this.commonData.acp_default_location); // fleshed
         copy.circulate('t');
         copy.holdable('t');
         copy.opac_visible('t');
@@ -487,9 +392,11 @@ export class VolCopyService {
             err => {},
             () => {
                 recordIds.forEach(bibId => {
-                    this.bibParts[bibId] = this.bibParts[bibId]
-                    .sort((p1, p2) =>
-                        p1.label_sortkey() < p2.label_sortkey() ? -1 : 1);
+                    if (this.bibParts[bibId]) {
+                        this.bibParts[bibId] = this.bibParts[bibId]
+                        .sort((p1, p2) =>
+                            p1.label_sortkey() < p2.label_sortkey() ? -1 : 1);
+                    }
                 });
             }
         );
index f907b3b..9c2b4a5 100644 (file)
@@ -20,10 +20,6 @@ export interface CallNumData {
 @Injectable()
 export class HoldingsService {
 
-    callNumberClasses: IdlObject[];
-    callNumberPrefixes: IdlObject[];
-    callNumberSuffixes: IdlObject[];
-
     constructor(
         private net: NetService,
         private auth: AuthService,
@@ -68,47 +64,5 @@ export class HoldingsService {
             });
         });
     }
-
-    // Returns a sorted list of call number classes
-    fetchCallNumberClasses(): Promise<IdlObject[]> {
-        if (this.callNumberClasses) {
-            return Promise.resolve(this.callNumberClasses);
-        }
-
-        return this.pcrud.retrieveAll('acnc', {}, {atomic: true})
-        .toPromise().then(classes => {
-            this.callNumberClasses = classes.sort(
-                (c1, c2) => c1.name() < c2.name() ? -1 : 1);
-            return this.callNumberClasses;
-        });
-    }
-
-    // Returns a sorted list of call number prefixes
-    fetchCallNumberPrefixes(): Promise<IdlObject[]> {
-        if (this.callNumberPrefixes) {
-            return Promise.resolve(this.callNumberPrefixes);
-        }
-
-        return this.pcrud.retrieveAll('acnp', {}, {atomic: true})
-        .toPromise().then(prefixes => {
-            this.callNumberPrefixes = prefixes.sort(
-                (c1, c2) => c1.label_sortkey() < c2.label_sortkey() ? -1 : 1);
-            return this.callNumberPrefixes;
-        });
-    }
-
-    // Returns a sorted list of call number suffixes
-    fetchCallNumberSuffixes(): Promise<IdlObject[]> {
-        if (this.callNumberSuffixes) {
-            return Promise.resolve(this.callNumberSuffixes);
-        }
-
-        return this.pcrud.retrieveAll('acns', {}, {atomic: true})
-        .toPromise().then(suffixes => {
-            this.callNumberSuffixes = suffixes.sort(
-                (c1, c2) => c1.label_sortkey() < c2.label_sortkey() ? -1 : 1);
-            return this.callNumberSuffixes;
-        });
-    }
 }