LP1806087 Angular catalog Ang7 & lint repairs
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / share / hold.service.ts
1 /**
2  * Common code for mananging holdings
3  */
4 import {Injectable, EventEmitter} from '@angular/core';
5 import {Observable} from 'rxjs';
6 import {map, mergeMap} from 'rxjs/operators';
7 import {IdlObject} from '@eg/core/idl.service';
8 import {NetService} from '@eg/core/net.service';
9 import {PcrudService} from '@eg/core/pcrud.service';
10 import {EventService, EgEvent} from '@eg/core/event.service';
11 import {AuthService} from '@eg/core/auth.service';
12 import {BibRecordService,
13     BibRecordSummary} from '@eg/share/catalog/bib-record.service';
14
15 // Response from a place-holds API call.
16 export interface HoldRequestResult {
17     success: boolean;
18     holdId?: number;
19     evt?: EgEvent;
20 }
21
22 // Values passed to the place-holds API call.
23 export interface HoldRequest {
24     holdType: string;
25     holdTarget: number;
26     recipient: number;
27     requestor: number;
28     pickupLib: number;
29     override?: boolean;
30     notifyEmail?: boolean;
31     notifyPhone?: string;
32     notifySms?: string;
33     smsCarrier?: string;
34     thawDate?: string; // ISO date
35     frozen?: boolean;
36     holdableFormats?: {[target: number]: string};
37     result?: HoldRequestResult;
38 }
39
40 // A fleshed hold request target object containing whatever data is
41 // available for each hold type / target.  E.g. a TITLE hold will
42 // not have a value for 'volume', but a COPY hold will, since all
43 // copies have volumes.  Every HoldRequestTarget will have a bibId and
44 // bibSummary.  Some values come directly from the API call, others
45 // applied locally.
46 export interface HoldRequestTarget {
47     target: number;
48     metarecord?: IdlObject;
49     bibrecord?: IdlObject;
50     bibId?: number;
51     bibSummary?: BibRecordSummary;
52     part?: IdlObject;
53     volume?: IdlObject;
54     copy?: IdlObject;
55     issuance?: IdlObject;
56     metarecord_filters?: any;
57 }
58
59 @Injectable()
60 export class HoldService {
61
62     constructor(
63         private evt: EventService,
64         private net: NetService,
65         private pcrud: PcrudService,
66         private auth: AuthService,
67         private bib: BibRecordService,
68     ) {}
69
70     placeHold(request: HoldRequest): Observable<HoldRequest> {
71
72         let method = 'open-ils.circ.holds.test_and_create.batch';
73         if (request.override) { method = method + '.override'; }
74
75         return this.net.request(
76             'open-ils.circ', method, this.auth.token(), {
77                 patronid:       request.recipient,
78                 pickup_lib:     request.pickupLib,
79                 hold_type:      request.holdType,
80                 email_notify:   request.notifyEmail,
81                 phone_notify:   request.notifyPhone,
82                 thaw_date:      request.thawDate,
83                 frozen:         request.frozen,
84                 sms_notify:     request.notifySms,
85                 sms_carrier:    request.smsCarrier,
86                 holdable_formats_map: request.holdableFormats
87             },
88             [request.holdTarget]
89         ).pipe(map(
90             resp => {
91                 let result = resp.result;
92                 const holdResult: HoldRequestResult = {success: true};
93
94                 // API can return an ID, an array of events, or a hash
95                 // of info.
96
97                 if (Number(result) > 0) {
98                     // On success, the API returns the hold ID.
99                     holdResult.holdId = result;
100                     console.debug(`Hold successfully placed ${result}`);
101
102                 } else {
103                     holdResult.success = false;
104                     console.info('Hold request failed: ', result);
105
106                     if (Array.isArray(result)) { result = result[0]; }
107
108                     if (this.evt.parse(result)) {
109                         holdResult.evt = this.evt.parse(result);
110                     } else {
111                         holdResult.evt = this.evt.parse(result.last_event);
112                     }
113                 }
114
115                 request.result = holdResult;
116                 return request;
117             }
118         ));
119     }
120
121     getHoldTargetMeta(holdType: string, holdTarget: number | number[],
122         orgId?: number): Observable<HoldRequestTarget> {
123
124         const targetIds = [].concat(holdTarget);
125
126         return this.net.request(
127             'open-ils.circ',
128             'open-ils.circ.hold.get_metadata',
129             holdType, targetIds, orgId
130         ).pipe(mergeMap(meta => {
131             const target: HoldRequestTarget = meta;
132             target.bibId = target.bibrecord.id();
133
134             return this.bib.getBibSummary(target.bibId)
135             .pipe(map(sum => {
136                 target.bibSummary = sum;
137                 return target;
138             }));
139         }));
140     }
141 }
142