]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/staff/share/holds/holds.service.ts
LP1615805 No inputs after submit in patron search (AngularJS)
[Evergreen.git] / Open-ILS / src / eg2 / src / app / staff / share / holds / holds.service.ts
1 /**
2  * Common code for mananging holds
3  */
4 import {Injectable} 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 'callNum', but a COPY hold will, since all
43 // copies have call numbers.  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     parts?: IdlObject[];
54     callNum?: IdlObject;
55     copy?: IdlObject;
56     issuance?: IdlObject;
57     metarecord_filters?: any;
58     part_required?: boolean;
59 }
60
61 /** Service for performing various hold-related actions */
62
63 @Injectable()
64 export class HoldsService {
65
66     constructor(
67         private evt: EventService,
68         private net: NetService,
69         private auth: AuthService,
70         private bib: BibRecordService,
71     ) {}
72
73     placeHold(request: HoldRequest): Observable<HoldRequest> {
74
75         let method = 'open-ils.circ.holds.test_and_create.batch';
76         if (request.override) { method = method + '.override'; }
77
78         return this.net.request(
79             'open-ils.circ', method, this.auth.token(), {
80                 patronid:       request.recipient,
81                 pickup_lib:     request.pickupLib,
82                 hold_type:      request.holdType,
83                 email_notify:   request.notifyEmail,
84                 phone_notify:   request.notifyPhone,
85                 thaw_date:      request.thawDate,
86                 frozen:         request.frozen,
87                 sms_notify:     request.notifySms,
88                 sms_carrier:    request.smsCarrier,
89                 holdable_formats_map: request.holdableFormats
90             },
91             [request.holdTarget]
92         ).pipe(map(
93             resp => {
94                 let result = resp.result;
95                 const holdResult: HoldRequestResult = {success: true};
96
97                 // API can return an ID, an array of events, or a hash
98                 // of info.
99
100                 if (Number(result) > 0) {
101                     // On success, the API returns the hold ID.
102                     holdResult.holdId = result;
103                     console.debug(`Hold successfully placed ${result}`);
104
105                 } else {
106                     holdResult.success = false;
107                     console.info('Hold request failed: ', result);
108
109                     if (Array.isArray(result)) { result = result[0]; }
110
111                     if (this.evt.parse(result)) {
112                         holdResult.evt = this.evt.parse(result);
113                     } else {
114                         holdResult.evt = this.evt.parse(result.last_event);
115                     }
116                 }
117
118                 request.result = holdResult;
119                 return request;
120             }
121         ));
122     }
123
124     getHoldTargetMeta(holdType: string, holdTarget: number | number[],
125         orgId?: number): Observable<HoldRequestTarget> {
126
127         const targetIds = [].concat(holdTarget);
128
129         return this.net.request(
130             'open-ils.circ',
131             'open-ils.circ.hold.get_metadata',
132             holdType, targetIds, orgId
133         ).pipe(mergeMap(meta => {
134             const target: HoldRequestTarget = meta;
135             target.bibId = target.bibrecord.id();
136             target.callNum = meta.volume; // map to client terminology
137
138             return this.bib.getBibSummary(target.bibId)
139                 .pipe(map(sum => {
140                     target.bibSummary = sum;
141                     return target;
142                 }));
143         }));
144     }
145
146     /**
147       * Update a list of holds.
148       * Returns observable of results, one per hold.
149       * Result is either a Number (hold ID) or an EgEvent object.
150       */
151     updateHolds(holds: IdlObject[]): Observable<any> {
152
153         return this.net.request(
154             'open-ils.circ',
155             'open-ils.circ.hold.update.batch',
156             this.auth.token(), holds
157         ).pipe(map(response => {
158
159             if (Number(response) > 0) { return Number(response); }
160
161             if (Array.isArray(response)) { response = response[0]; }
162
163             const evt = this.evt.parse(response);
164
165             console.warn('Hold update returned event', evt);
166             return evt;
167         }));
168     }
169 }
170
171
172