2 * Common code for mananging holds
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';
15 // Response from a place-holds API call.
16 export interface HoldRequestResult {
22 // Values passed to the place-holds API call.
23 export interface HoldRequest {
30 notifyEmail?: boolean;
34 thawDate?: string; // ISO date
36 holdableFormats?: {[target: number]: string};
37 result?: HoldRequestResult;
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
46 export interface HoldRequestTarget {
48 metarecord?: IdlObject;
49 bibrecord?: IdlObject;
51 bibSummary?: BibRecordSummary;
57 metarecord_filters?: any;
58 part_required?: boolean;
61 /** Service for performing various hold-related actions */
64 export class HoldsService {
67 private evt: EventService,
68 private net: NetService,
69 private auth: AuthService,
70 private bib: BibRecordService,
73 placeHold(request: HoldRequest): Observable<HoldRequest> {
75 let method = 'open-ils.circ.holds.test_and_create.batch';
76 if (request.override) { method = method + '.override'; }
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
94 let result = resp.result;
95 const holdResult: HoldRequestResult = {success: true};
97 // API can return an ID, an array of events, or a hash
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}`);
106 holdResult.success = false;
107 console.info('Hold request failed: ', result);
109 if (Array.isArray(result)) { result = result[0]; }
111 if (this.evt.parse(result)) {
112 holdResult.evt = this.evt.parse(result);
114 holdResult.evt = this.evt.parse(result.last_event);
118 request.result = holdResult;
124 getHoldTargetMeta(holdType: string, holdTarget: number | number[],
125 orgId?: number): Observable<HoldRequestTarget> {
127 const targetIds = [].concat(holdTarget);
129 return this.net.request(
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
138 return this.bib.getBibSummary(target.bibId)
140 target.bibSummary = sum;
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.
151 updateHolds(holds: IdlObject[]): Observable<any> {
153 return this.net.request(
155 'open-ils.circ.hold.update.batch',
156 this.auth.token(), holds
157 ).pipe(map(response => {
159 if (Number(response) > 0) { return Number(response); }
161 if (Array.isArray(response)) { response = response[0]; }
163 const evt = this.evt.parse(response);
165 console.warn('Hold update returned event', evt);