]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/opac/skin/default/js/holds.js
start adding metarecord hold support
[working/Evergreen.git] / Open-ILS / web / opac / skin / default / js / holds.js
1 var holdsOrgSelectorBuilt = false;
2 var holdArgs;
3
4 /* 
5 note: metarecord holds have a holdable_formats field that contains
6 item_type(s)-item_forms(s)-language
7 item_form and language are optional - if language exist and no 
8 item_form is specified, use item_type(s)--language
9 */
10
11 function holdsHandleStaff() {
12         swapCanvas($('xulholds_box'));
13         $('xul_recipient_barcode').focus();
14         $('xul_recipient_barcode').onkeypress = function(evt) 
15                 {if(userPressedEnter(evt)) { _holdsHandleStaff(); } };
16         $('xul_recipient_barcode_submit').onclick = _holdsHandleStaff;
17         $('xul_recipient_me').onclick = _holdsHandleStaffMe;
18 }
19
20 function _holdsHandleStaffMe() {
21         holdArgs.recipient = G.user;
22         holdsDrawEditor();
23 }
24
25 function _holdsHandleStaff() {
26         var barcode = $('xul_recipient_barcode').value;
27         var user = grabUserByBarcode( G.user.session, barcode );
28         if(!user) return;
29         holdArgs.recipient = user;
30         holdsDrawEditor();
31 }
32
33
34 /** args:
35   * record, volume, copy (ids)
36   * request, recipient, editHold (objects)
37   */
38 function holdsDrawEditor(args) {
39
40         holdArgs = (args) ? args : holdArgs;
41
42         if(isXUL() && holdArgs.recipient == null 
43                         && holdArgs.editHold == null) {
44                 holdsHandleStaff();
45                 return;
46         }
47
48         if(!holdArgs.recipient) holdArgs.recipient = G.user;
49         if(!holdArgs.requestor) holdArgs.requestor = G.user;
50
51         if(!(holdArgs.requestor && holdArgs.requestor.session)) {
52                 detachAllEvt('common','locationChanged');
53                 attachEvt('common','loggedIn', holdsDrawEditor)
54                 initLogin();
55                 return;
56         }
57
58         if(holdArgs.editHold) /* flesh the args with the existing hold */
59                 holdArgsFromHold(holdArgs.editHold, holdArgs);
60
61         holdsDrawWindow();
62
63         if(holdArgs.editHold) {
64                 hideMe($('holds_submit'));
65                 unHideMe($('holds_update'));
66                 var req = new Request(FETCH_HOLD_STATUS, 
67                         G.user.session, holdArgs.editHold.id());
68                 req.send(true);
69                 holdArgs.status = req.result();
70                 _holdsUpdateEditHold();
71         }  
72 }
73
74
75 /* updates the edit window with the existing hold's data */
76 function _holdsUpdateEditHold() {
77
78         var hold = holdArgs.editHold;
79         var status = holdArgs.status;
80
81         var orgsel = $('holds_org_selector');
82         setSelector(orgsel, hold.pickup_lib());
83
84         if( hold.capture_time() || status > 2 )
85                 orgsel.disabled = true;
86         else    
87                 orgsel.disabled = false;
88
89
90         $('holds_submit').onclick = holdsEditHold;
91         $('holds_update').onclick = holdsEditHold;
92
93         if(hold.phone_notify()) {
94                 $('holds_enable_phone').checked = true;
95                 $('holds_phone').value = hold.phone_notify();
96
97         } else {
98                 $('holds_phone').disabled = true;
99                 $('holds_enable_phone').checked = false;
100         }
101
102         if(hold.email_notify()) {
103                 $('holds_enable_email').checked = true;
104
105         } else {
106                 $('holds_enable_email').checked = false;
107         }
108 }
109
110 function holdsEditHold() {
111         var hold = holdsBuildHoldFromWindow();
112         if(!hold) return;
113         holdsUpdate(hold);
114         showCanvas();
115         if(holdArgs.onComplete)
116                 holdArgs.onComplete(hold);
117 }
118
119 function holdArgsFromHold(hold, oargs) {
120         var args = (oargs) ? oargs : {};
121         args.type = hold.hold_type();
122         var target = hold.target();
123
124         switch(args.type) {
125                 case 'M':
126                         args.metarecord = target;
127                         break;
128                 case 'T':
129                         args.record = target;
130                         break;
131                 case 'V':
132                         args.volume = target;
133                         break;
134                 case 'C':
135                         args.copy = target;
136                         break;
137         }
138         return args;
139 }
140
141 function holdFetchObjects(hold, doneCallback) {
142
143         var args = (hold) ? holdArgsFromHold(hold) : holdArgs;
144
145         var type = args.type;
146
147         if( type == 'C' ) {
148
149                 if( args.copyObject ) {
150
151                         args.copy = args.copyObject.id();
152                         args.volume = args.copyObject.call_number();
153                         _h_set_vol(args, doneCallback);
154
155                 } else {
156                         var creq = new Request(FETCH_COPY, args.copy);
157
158                         creq.callback(
159                                 function(r) {
160                                         var cp = r.getResultObject();
161                                         args.copyObject = cp;
162                                         args.volume = args.copyObject.call_number();
163                                         _h_set_vol(args, doneCallback);
164                                 }
165                         );
166                         creq.send();
167                 }
168         } else {
169                 if( type == 'V' ) {
170                         _h_set_vol(args, doneCallback);
171
172                 } else {
173                         if( type == 'T' ) {
174                                 _h_set_rec(args, doneCallback);
175                         }
176                 }
177         }
178
179         return args;
180 }
181
182 function _h_set_vol(args, doneCallback) {
183
184         if( args.volumeObject ) {
185                 args.volume = args.volumeObject.id();
186                 args.record = args.volumeObject.record();
187                 _h_set_rec(args, doneCallback);
188
189         } else {
190
191                 var vreq = new Request(FETCH_VOLUME, args.volume);
192                 vreq.callback(
193                         function(r) {
194                                 var vol = r.getResultObject();
195                                 args.volumeObject = vol;
196                                 args.record = vol.record();
197                                 _h_set_rec(args, doneCallback);
198                         }
199                 );
200                 vreq.send();
201         }
202 }
203
204 function _h_set_rec(args, doneCallback) {
205         if(args.recordObject) {
206                 args.record = args.recordObject.doc_id();
207         } else {
208                 args.recordObject = findRecord( args.record, 'T' );
209         }
210
211         if( args.type == 'T' || args.type == 'M' ) {
212                 _h_set_rec_descriptors(args, doneCallback);
213         } else {
214                 if(doneCallback) doneCallback(args);
215         }
216 }
217
218 function _h_set_rec_descriptors(args, doneCallback) {
219
220         /* grab the list of record desciptors attached to this records metarecord */
221         if( ! args.recordDescriptors )  {
222                 var params = { record: args.record };
223
224                 if( ! args.record ) {
225                         if( args.metarecord )
226                                 params = { metarecord : args.metarecord };
227                         else 
228                                 params = { metarecord : args.metarecordObject.id() };
229                 }
230
231                 var req = new Request(FETCH_MR_DESCRIPTORS, params );
232                 req.callback(
233                         function(r) {
234                                 args.recordDescriptors = r.getResultObject();
235                                 if(doneCallback) doneCallback(args);
236                         }
237                 );
238                 req.send();
239
240         } else {
241                 if(doneCallback) doneCallback(args);
242         }
243 }
244
245
246
247 function holdsDrawWindow() {
248         swapCanvas($('holds_box'));
249         $('holds_cancel').onclick = function(){ runEvt('common', 'holdUpdateCanceled'), showCanvas() };
250         $('holds_submit').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
251         $('holds_update').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
252         holdFetchObjects(null, function(){__holdsDrawWindow();});
253 }
254
255 function __holdsDrawWindow() {
256
257         var rec = holdArgs.recordObject;
258         var vol = holdArgs.volumeObject;
259         var copy = holdArgs.copyObject;
260
261         if(!holdsOrgSelectorBuilt) {
262                 holdsBuildOrgSelector(null,0);
263                 holdsOrgSelectorBuilt = true;
264         }
265
266         if(isXUL()) {
267                 var dsel = $('holds_depth_selector');
268                 unHideMe($('holds_depth_selector_row'));
269                 if(dsel.getElementsByTagName('option').length == 0) {
270                         var types = globalOrgTypes;
271                         var depth = findOrgDepth(G.user.ws_ou());
272                         iterate(types, 
273                                 function(t) {
274                                         if(t.depth() > depth) return;
275                                         insertSelectorVal(dsel, -1, t.opac_label(), t.depth());
276                                 }
277                         );
278                 }
279         }
280
281         appendClear($('holds_recipient'), text(
282                 holdArgs.recipient.family_name() + ', ' +  
283                         holdArgs.recipient.first_given_name()));
284         appendClear($('holds_title'), text(rec.title()));
285         appendClear($('holds_author'), text(rec.author()));
286
287         if( holdArgs.type == 'V' || holdArgs.type == 'C' ) {
288
289                 unHideMe($('holds_type_row'));
290                 unHideMe($('holds_cn_row'));
291                 appendClear($('holds_cn'), text(holdArgs.volumeObject.label()));
292
293                 if( holdArgs.type == 'V'  ) {
294                         unHideMe($('holds_is_cn'));
295                         hideMe($('holds_is_copy'));
296
297                 } else {
298                         hideMe($('holds_is_cn'));
299                         unHideMe($('holds_is_copy'));
300                         unHideMe($('holds_copy_row'));
301                         appendClear($('holds_copy'), text(holdArgs.copyObject.barcode()));
302                 }
303
304         } else {
305                 hideMe($('holds_type_row'));
306                 hideMe($('holds_copy_row'));
307                 hideMe($('holds_cn_row'));
308         }
309
310         removeChildren($('holds_format'));
311         for( var i in rec.types_of_resource() ) {
312                 var res = rec.types_of_resource()[i];
313                 var img = elem("img");
314                 setResourcePic(img, res);
315                 $('holds_format').appendChild(text(' '+res+' '));
316                 $('holds_format').appendChild(img);
317                 $('holds_format').appendChild(text(' '));
318         }
319
320
321         $('holds_phone').value = holdArgs.recipient.day_phone();
322         appendClear( $('holds_email'), text(holdArgs.recipient.email()));
323
324         var pref = G.user.prefs[PREF_HOLD_NOTIFY];
325
326         if(pref) {
327                 if( ! pref.match(/email/i) ) 
328                         $('holds_enable_email').checked = false;
329
330                 if( ! pref.match(/phone/i) ) {
331                         $('holds_phone').disabled = true;
332                         $('holds_enable_phone').checked = false;
333                 }
334         }
335
336         appendClear($('holds_physical_desc'), text(rec.physical_description()));
337
338         if(holdArgs.type == 'M') hideMe($('hold_physical_desc_row'));
339
340         holdsSetFormatSelector();
341 }
342
343 function holdsSetFormatSelector() {
344         var type = holdArgs.type;
345         if( type == 'C' || type == 'V' ) return;
346
347         var data = holdGetAvailableTypesAndForms();
348         var avail_types = data.avail_types;
349         var avail_forms = data.avail_forms;
350         var item_lang   = data.item_lang;
351
352         /*
353         if( avail_types.length > 1 || avail_forms.length > 1 ) {
354                 unHideMe($('holds_alt_formats_row'));
355                 alert('lang: ' + item_lang + '\navail types: ' + avail_types + '\navail forms: ' + avail_forms);
356         }
357         */
358 }
359
360
361 function holdGetAvailableTypesAndForms() {
362
363         var item_types = [];
364         var item_forms  = [];
365         var item_lang;
366
367         var type = holdArgs.type;
368         var desc = holdArgs.recordDescriptors;
369         var rec = holdArgs.record;
370         var mrec = holdArgs.metarecord;
371
372         if( type == 'T' ) {
373
374                 /* find our language */
375                 for( var i = 0; i < desc.length; i++ ) {
376                         var d = desc[i];
377                         if( d.record() == holdArgs.record ) {
378                                 item_lang = d.item_lang();
379                                 break;
380                         }
381                 }
382         }
383
384         for( var i = 0; i < desc.length; i++ ) {
385                 var d = desc[i];
386                 if( d.item_lang() != item_lang ) continue;
387                 item_types.push(d.item_type());
388                 item_forms.push(d.item_form());
389         }
390
391         item_types = uniquify(item_types);
392         item_forms = uniquify(item_forms);
393
394         return { 
395                 avail_types : item_types, 
396                 avail_forms     : item_forms, 
397                 item_lang : item_lang 
398         };
399 }
400
401
402 function holdsCheckPossibility(pickuplib) {
403         var rec = holdArgs.record;
404         var type = holdArgs.type;
405         var req = new Request(CHECK_HOLD_POSSIBLE, G.user.session, 
406                         { titleid : rec, patronid : G.user.id(), depth : 0, pickup_lib : pickuplib } );
407         req.send(true);
408         return req.result();
409 }
410
411
412 function holdsBuildOrgSelector(node) {
413
414         if(!node) node = globalOrgTree;
415
416         var selector = $('holds_org_selector');
417         var index = selector.options.length;
418
419         var type = findOrgType(node.ou_type());
420         var indent = type.depth() - 1;
421         var opt = setSelectorVal( selector, index, node.name(), node.id(), null, indent );
422         if(!type.can_have_vols()) opt.disabled = true;
423         
424         if( node.id() == holdArgs.recipient.home_ou() ) {
425                 selector.selectedIndex = index;
426                 selector.options[index].selected = true;        
427         }
428
429         for( var i in node.children() ) {
430                 var child = node.children()[i];
431                 if(child) holdsBuildOrgSelector(child);
432         }
433 }
434
435 function holdsBuildHoldFromWindow() {
436
437         var org = $('holds_org_selector').options[
438                 $('holds_org_selector').selectedIndex].value;
439
440         var hold = new ahr();
441         if(holdArgs.editHold) {
442                 hold = holdArgs.editHold;
443                 holdArgs.editHold = null;
444         }
445
446         if( $('holds_enable_phone').checked ) {
447                 var phone = $('holds_phone').value;
448                 if( !phone || !phone.match(REGEX_PHONE) ) {
449                         alert($('holds_bad_phone').innerHTML);
450                         return null;
451                 }
452                 hold.phone_notify(phone);
453
454         } else {
455                 hold.phone_notify("");
456         }
457
458         if( $('holds_enable_email').checked ) 
459                 hold.email_notify(1);
460         else
461                 hold.email_notify(0);
462
463         var target;
464
465         switch(holdArgs.type) {
466                 case 'M':
467                         target = holdArgs.metarecord;
468                         break;
469                 case 'T':
470                         target = holdArgs.record;
471                         break;
472                 case 'V':
473                         target = holdArgs.volume;
474                         break;
475                 case 'C':
476                         target = holdArgs.copy;
477                         break;
478         }
479
480
481         hold.pickup_lib(org); 
482         hold.request_lib(org); 
483         hold.requestor(holdArgs.requestor.id());
484         hold.usr(holdArgs.recipient.id());
485         hold.hold_type(holdArgs.type);
486         hold.target(target);
487
488         if(isXUL())             
489                 hold.selection_depth(getSelectorVal($('holds_depth_selector')));
490         return hold;
491 }
492         
493 function holdsPlaceHold(hold) {
494
495         if(!hold) return;
496
497         swapCanvas($('check_holds_box'));
498
499         if( holdArgs.type == 'M' || holdArgs.type == 'T' ) {
500                 if( ! holdsCheckPossibility(hold.pickup_lib() ) ) {
501                         alert($('hold_not_allowed').innerHTML);
502                         swapCanvas($('holds_box'));
503                         return;
504                 }
505         }
506
507         var req = new Request( CREATE_HOLD, holdArgs.requestor.session, hold );
508         req.send(true);
509         var res = req.result();
510
511         if( res == '1' ) alert($('holds_success').innerHTML);
512         else alert($('holds_failure').innerHTML);
513         
514         showCanvas();
515
516         holdArgs = null;
517         runEvt('common', 'holdUpdated');
518 }
519
520 function holdsCancel(holdid, user) {
521         if(!user) user = G.user;
522         var req = new Request(CANCEL_HOLD, user.session, holdid);
523         req.send(true);
524         return req.result();
525         runEvt('common', 'holdUpdated');
526 }
527
528 function holdsUpdate(hold, user) {
529         if(!user) user = G.user;
530         var req = new Request(UPDATE_HOLD, user.session, hold);
531         req.send(true);
532         var x = req.result(); /* cause an exception if there is one */
533         runEvt('common', 'holdUpdated');
534 }
535
536
537
538