999ce372ee6a0f1576eda67d73ee0379f37012a1
[evergreen-equinox.git] / Open-ILS / src / eg2 / src / app / share / catalog / bib-record.service.ts
1 import {Injectable} from '@angular/core';
2 import {Observable, from} from 'rxjs';
3 import {mergeMap, map, tap} from 'rxjs/operators';
4 import {OrgService} from '@eg/core/org.service';
5 import {UnapiService} from '@eg/share/catalog/unapi.service';
6 import {IdlService, IdlObject} from '@eg/core/idl.service';
7 import {NetService} from '@eg/core/net.service';
8 import {PcrudService} from '@eg/core/pcrud.service';
9
10 export const NAMESPACE_MAPS = {
11     'mods':     'http://www.loc.gov/mods/v3',
12     'biblio':   'http://open-ils.org/spec/biblio/v1',
13     'holdings': 'http://open-ils.org/spec/holdings/v1',
14     'indexing': 'http://open-ils.org/spec/indexing/v1'
15 };
16
17 export const HOLDINGS_XPATH =
18     '/holdings:holdings/holdings:counts/holdings:count';
19
20 interface EResourceUrl {
21     href: string;
22     note: string;
23     label: string;
24 }
25
26 export class BibRecordSummary {
27     id: number; // == record.id() for convenience
28     metabibId: number; // If present, this is a metabib summary
29     metabibRecords: number[]; // all constituent bib records
30     orgId: number;
31     orgDepth: number;
32     record: IdlObject;
33     display: any;
34     attributes: any;
35     holdingsSummary: any;
36     holdCount: number;
37     bibCallNumber: string;
38     net: NetService;
39     displayHighlights: {[name: string]: string | string[]} = {};
40     eResourceUrls: EResourceUrl[] = [];
41     copies: any[];
42
43     constructor(record: IdlObject, orgId: number, orgDepth?: number) {
44         this.id = Number(record.id());
45         this.record = record;
46         this.orgId = orgId;
47         this.orgDepth = orgDepth;
48         this.display = {};
49         this.attributes = {};
50         this.bibCallNumber = null;
51         this.metabibRecords = [];
52     }
53
54     // Get -> Set -> Return bib-level call number
55     getBibCallNumber(): Promise<string> {
56
57         if (this.bibCallNumber !== null) {
58             return Promise.resolve(this.bibCallNumber);
59         }
60
61         return this.net.request(
62             'open-ils.cat',
63             'open-ils.cat.biblio.record.marc_cn.retrieve',
64             this.id, null, this.orgId
65         ).toPromise().then(cnArray => {
66             if (cnArray && cnArray.length > 0) {
67                 const key1 = Object.keys(cnArray[0])[0];
68                 this.bibCallNumber = cnArray[0][key1];
69             } else {
70                 this.bibCallNumber = '';
71             }
72             return this.bibCallNumber;
73         });
74     }
75 }
76
77 @Injectable()
78 export class BibRecordService {
79
80     // Cache of bib editor / creator objects
81     // Assumption is this list will be limited in size.
82     userCache: {[id: number]: IdlObject};
83
84     constructor(
85         private idl: IdlService,
86         private net: NetService,
87         private org: OrgService,
88         private unapi: UnapiService,
89         private pcrud: PcrudService
90     ) {
91         this.userCache = {};
92     }
93
94     getBibSummary(id: number,
95         orgId?: number, isStaff?: boolean): Observable<BibRecordSummary> {
96         return this.getBibSummaries([id], orgId, isStaff);
97     }
98
99     getBibSummaries(bibIds: number[], orgId?: number,
100         isStaff?: boolean, options?: any): Observable<BibRecordSummary> {
101
102         if (bibIds.length === 0) { return from([]); }
103         if (!orgId) { orgId = this.org.root().id(); }
104
105         let method = 'open-ils.search.biblio.record.catalog_summary';
106         if (isStaff) { method += '.staff'; }
107
108         return this.net.request('open-ils.search', method, orgId, bibIds, options)
109         .pipe(map(bibSummary => {
110             const summary = new BibRecordSummary(bibSummary.record, orgId);
111             summary.net = this.net; // inject
112             summary.display = bibSummary.display;
113             summary.attributes = bibSummary.attributes;
114             summary.holdCount = bibSummary.hold_count;
115             summary.holdingsSummary = bibSummary.copy_counts;
116             summary.eResourceUrls = bibSummary.urls;
117             summary.copies = bibSummary.copies;
118
119             return summary;
120         }));
121     }
122
123     getMetabibSummaries(metabibIds: number[],
124         orgId?: number, isStaff?: boolean, options?: any): Observable<BibRecordSummary> {
125
126         if (metabibIds.length === 0) { return from([]); }
127         if (!orgId) { orgId = this.org.root().id(); }
128
129         let method = 'open-ils.search.biblio.metabib.catalog_summary';
130         if (isStaff) { method += '.staff'; }
131
132         return this.net.request('open-ils.search', method, orgId, metabibIds, options)
133         .pipe(map(metabibSummary => {
134             const summary = new BibRecordSummary(metabibSummary.record, orgId);
135             summary.net = this.net; // inject
136             summary.metabibId = Number(metabibSummary.metabib_id);
137             summary.metabibRecords = metabibSummary.metabib_records;
138             summary.display = metabibSummary.display;
139             summary.attributes = metabibSummary.attributes;
140             summary.holdCount = metabibSummary.hold_count;
141             summary.holdingsSummary = metabibSummary.copy_counts;
142             summary.copies = metabibSummary.copies;
143
144             return summary;
145         }));
146     }
147 }
148
149