]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/opac/skin/default/js/holds.js
added sanity check for IE hold placer since disabled is not supported
[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
35 /** args:
36   * record, volume, copy (ids)
37   * request, recipient, editHold (objects)
38   */
39
40 function holdsDrawEditor(args) {
41
42         holdArgs = (args) ? args : holdArgs;
43
44         if(isXUL() && holdArgs.recipient == null 
45                         && holdArgs.editHold == null) {
46                 holdsHandleStaff();
47                 return;
48         }
49
50         if(!holdArgs.recipient) holdArgs.recipient = G.user;
51         if(!holdArgs.requestor) holdArgs.requestor = G.user;
52
53         if(!(holdArgs.requestor && holdArgs.requestor.session)) {
54                 detachAllEvt('common','locationChanged');
55                 attachEvt('common','loggedIn', holdsDrawEditor)
56                 initLogin();
57                 return;
58         }
59
60         if(holdArgs.editHold) // flesh the args with the existing hold 
61                 holdArgsFromHold(holdArgs.editHold, holdArgs);
62
63         holdsDrawWindow();
64 }
65
66
67 // updates the edit window with the existing hold's data 
68 function _holdsUpdateEditHold() {
69
70         var hold = holdArgs.editHold;
71         var status = holdArgs.status;
72
73         var orgsel = $('holds_org_selector');
74         setSelector(orgsel, hold.pickup_lib());
75
76         if( hold.capture_time() || status > 2 )
77                 orgsel.disabled = true;
78         else    
79                 orgsel.disabled = false;
80
81
82         $('holds_submit').onclick = holdsEditHold;
83         $('holds_update').onclick = holdsEditHold;
84
85         if(hold.phone_notify()) {
86                 $('holds_enable_phone').checked = true;
87                 $('holds_phone').value = hold.phone_notify();
88
89         } else {
90                 $('holds_phone').disabled = true;
91                 $('holds_enable_phone').checked = false;
92         }
93
94         if(hold.email_notify()) {
95                 $('holds_enable_email').checked = true;
96
97         } else {
98                 $('holds_enable_email').checked = false;
99         }
100 }
101
102 function holdsEditHold() {
103         var hold = holdsBuildHoldFromWindow();
104         if(!hold) return;
105         holdsUpdate(hold);
106         showCanvas();
107         if(holdArgs.onComplete)
108                 holdArgs.onComplete(hold);
109 }
110
111 function holdArgsFromHold(hold, oargs) {
112         var args = (oargs) ? oargs : {};
113         args.type = hold.hold_type();
114         var target = hold.target();
115
116         switch(args.type) {
117                 case 'M':
118                         args.metarecord = target;
119                         break;
120                 case 'T':
121                         args.record = target;
122                         break;
123                 case 'V':
124                         args.volume = target;
125                         break;
126                 case 'C':
127                         args.copy = target;
128                         break;
129         }
130         return args;
131 }
132
133 function holdFetchObjects(hold, doneCallback) {
134
135         var args = (hold) ? holdArgsFromHold(hold) : holdArgs;
136
137         var type = args.type;
138
139         if( type == 'C' ) {
140
141                 if( args.copyObject ) {
142
143                         args.copy = args.copyObject.id();
144                         args.volume = args.copyObject.call_number();
145                         _h_set_vol(args, doneCallback);
146
147                 } else {
148                         var creq = new Request(FETCH_COPY, args.copy);
149
150                         creq.callback(
151                                 function(r) {
152                                         var cp = r.getResultObject();
153                                         args.copyObject = cp;
154                                         args.volume = args.copyObject.call_number();
155                                         _h_set_vol(args, doneCallback);
156                                 }
157                         );
158                         creq.send();
159                 }
160         } else {
161                 if( type == 'V' ) {
162                         _h_set_vol(args, doneCallback);
163
164                 } else {
165                         if( type == 'T' ) {
166                                 _h_set_rec(args, doneCallback);
167                         } else {
168                                 _h_set_rec_descriptors(args, doneCallback);
169                         }
170                 }
171         }
172
173         return args;
174 }
175
176 function _h_set_vol(args, doneCallback) {
177
178         if( args.volumeObject ) {
179                 args.volume = args.volumeObject.id();
180                 args.record = args.volumeObject.record();
181                 _h_set_rec(args, doneCallback);
182
183         } else {
184
185                 var vreq = new Request(FETCH_VOLUME, args.volume);
186                 vreq.callback(
187                         function(r) {
188                                 var vol = r.getResultObject();
189                                 args.volumeObject = vol;
190                                 args.record = vol.record();
191                                 _h_set_rec(args, doneCallback);
192                         }
193                 );
194                 vreq.send();
195         }
196 }
197
198 function _h_set_rec(args, doneCallback) {
199
200         if(args.recordObject) 
201                 args.record = args.recordObject.doc_id();
202         else 
203                 args.recordObject = findRecord( args.record, 'T' );
204         
205         if( args.type == 'T' || args.type == 'M' ) 
206                 _h_set_rec_descriptors(args, doneCallback);
207         else 
208                 if(doneCallback) doneCallback(args);
209 }
210
211
212 function _h_set_rec_descriptors(args, doneCallback) {
213
214         // grab the list of record desciptors attached to this records metarecord 
215         if( ! args.recordDescriptors )  {
216                 var params = { record: args.record };
217
218                 if( ! args.record ) {
219                         if( args.metarecord )
220                                 params = { metarecord : args.metarecord };
221                         else 
222                                 params = { metarecord : args.metarecordObject.doc_id() };
223                 }
224
225                 var req = new Request(FETCH_MR_DESCRIPTORS, params );
226                 req.callback(
227                         function(r) {
228                                 var data = r.getResultObject();
229                                 args.recordDescriptors = data.descriptors;
230                                 args.metarecord = data.metarecord;
231                                 if( args.type == 'M' && ! args.metarecordObject) 
232                                         args.metarecordObject = findRecord(args.metarecord, 'M');       
233                                  
234                                 if(doneCallback) doneCallback(args);
235                         }
236                 );
237                 req.send();
238
239         } else {
240                 if(doneCallback) doneCallback(args);
241         }
242
243         return args;
244 }
245
246
247
248 function holdsDrawWindow() {
249         swapCanvas($('holds_box'));
250         $('holds_cancel').onclick = function(){ runEvt('common', 'holdUpdateCanceled'), showCanvas() };
251         $('holds_submit').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
252         $('holds_update').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
253         holdFetchObjects(null, 
254                 function(){
255                         __holdsDrawWindow();
256
257                         if(holdArgs.editHold) {
258                                 hideMe($('holds_submit'));
259                                 unHideMe($('holds_update'));
260                                 var req = new Request(FETCH_HOLD_STATUS, 
261                                         G.user.session, holdArgs.editHold.id());
262                                 req.send(true);
263                                 holdArgs.status = req.result();
264                                 _holdsUpdateEditHold();
265                         }  
266                 }
267         );
268 }
269
270 function __holdsDrawWindow() {
271
272         var rec = holdArgs.recordObject;
273         var vol = holdArgs.volumeObject;
274         var copy = holdArgs.copyObject;
275         var mr = holdArgs.metarecordObject;
276
277         rec = (rec) ? rec : mr;
278
279         if(!holdsOrgSelectorBuilt) {
280                 holdsBuildOrgSelector(null,0);
281                 holdsOrgSelectorBuilt = true;
282         }
283
284         if(isXUL()) {
285                 var dsel = $('holds_depth_selector');
286                 unHideMe($('holds_depth_selector_row'));
287                 if(dsel.getElementsByTagName('option').length == 0) {
288                         var types = globalOrgTypes;
289                         var depth = findOrgDepth(G.user.ws_ou());
290                         iterate(types, 
291                                 function(t) {
292                                         if(t.depth() > depth) return;
293                                         insertSelectorVal(dsel, -1, t.opac_label(), t.depth());
294                                 }
295                         );
296                 }
297         }
298
299         appendClear($('holds_recipient'), text(
300                 holdArgs.recipient.family_name() + ', ' +  
301                         holdArgs.recipient.first_given_name()));
302         appendClear($('holds_title'), text(rec.title()));
303         appendClear($('holds_author'), text(rec.author()));
304
305         if( holdArgs.type == 'V' || holdArgs.type == 'C' ) {
306
307                 unHideMe($('holds_type_row'));
308                 unHideMe($('holds_cn_row'));
309                 appendClear($('holds_cn'), text(holdArgs.volumeObject.label()));
310
311                 if( holdArgs.type == 'V'  ) {
312                         unHideMe($('holds_is_cn'));
313                         hideMe($('holds_is_copy'));
314
315                 } else {
316                         hideMe($('holds_is_cn'));
317                         unHideMe($('holds_is_copy'));
318                         unHideMe($('holds_copy_row'));
319                         appendClear($('holds_copy'), text(holdArgs.copyObject.barcode()));
320                 }
321
322         } else {
323                 hideMe($('holds_type_row'));
324                 hideMe($('holds_copy_row'));
325                 hideMe($('holds_cn_row'));
326         }
327
328         removeChildren($('holds_format'));
329
330         var mods_formats = rec.types_of_resource();
331         var formats;
332
333         if(holdArgs.recordDescriptors)
334                 formats = holdArgs.recordDescriptors[0].item_type();
335
336         if( holdArgs.type == 'T' ) {
337                 var desc = grep( holdArgs.recordDescriptors,
338                         function(i) {
339                                 return (i.record() == holdArgs.record); 
340                         }
341                 );
342                 formats = desc[0].item_type();
343         }
344
345         if( holdArgs.type == 'M' ) {
346                 var data = holdsParseMRFormats(holdArgs.editHold.holdable_formats());
347                 mods_formats = data.mods_formats;
348                 formats = data.formats;
349         }
350
351
352         for( var i in mods_formats ) {
353                 var res = mods_formats[i];
354                 var img = elem("img");
355                 setResourcePic(img, res);
356                 $('holds_format').appendChild(img);
357                 if(formats)
358                         $('holds_format').appendChild(text(' '+ MARCTypeToFriendly(formats[i]) +' '));
359                 else
360                         $('holds_format').appendChild(text(' '+ mods_formats[i] +' '));
361                 $('holds_format').appendChild(elem('br'));
362         }
363
364
365         $('holds_phone').value = holdArgs.recipient.day_phone();
366         appendClear( $('holds_email'), text(holdArgs.recipient.email()));
367
368         var pref = G.user.prefs[PREF_HOLD_NOTIFY];
369
370         if(pref) {
371                 if( ! pref.match(/email/i) ) 
372                         $('holds_enable_email').checked = false;
373
374                 if( ! pref.match(/phone/i) ) {
375                         $('holds_phone').disabled = true;
376                         $('holds_enable_phone').checked = false;
377                 }
378         }
379
380         appendClear($('holds_physical_desc'), text(rec.physical_description()));
381
382         if(holdArgs.type == 'M') hideMe($('hold_physical_desc_row'));
383
384         holdsSetFormatSelector();
385 }
386
387 function holdsParseMRFormats(str) {
388         var data = str.split(/-/);      
389
390         var formats = [];
391         var mods_formats = [];
392
393         for( var i = 0; i < data[0].length; i++ ) {
394                 formats.push( data[0].charAt(i) );
395                 mods_formats.push( MARCFormatToMods( formats[i] ) );
396         }
397         
398         formats = uniquify(formats);
399         mods_formats = uniquify(mods_formats);
400
401         return {
402                 formats                 : formats,
403                 mods_formats    : mods_formats,
404                 lang                            : data[2],
405                 largeprint              : data[1]
406         };
407 }
408
409
410 function holdsSetFormatSelector() {
411         var type = holdArgs.type;
412         if( type == 'C' || type == 'V' || holdArgs.editHold ) return;
413
414         var data                                = holdsGetFormats();
415         var avail_formats       = data.avail_formats;
416         var sel_formats = data.sel_formats;
417         holdArgs.language = data.lang;
418
419         unHideMe($('holds_alt_formats_row_extras'));
420         var selector = $('hold_alt_form_selector');
421
422         for( var i = 0; i < avail_formats.length; i++ ) {
423                 var form = avail_formats[i];
424                 unHideMe(findSelectorOptByValue(selector, form));
425         }
426 }
427
428
429 function holdsGetFormats() {
430
431         var lang;
432         var formats = [];
433         var sformats = []; // selected formats 
434
435         var type = holdArgs.type;
436         var desc = holdArgs.recordDescriptors;
437         var rec = holdArgs.record;
438         var mrec = holdArgs.metarecord;
439
440         if( type == 'T' ) {
441
442                 for( var i = 0; i < desc.length; i++ ) {
443                         var d = desc[i];
444                         if( d.record() == holdArgs.record ) {
445                                 lang = d.item_lang();
446                                 holdArgs.myFormat =  _t_f_2_format(d.item_type(), d.item_form());
447                                 sformats.push(holdArgs.myFormat);
448                                 break;
449                         }
450                 }
451         }
452
453         for( var i = 0; i < desc.length; i++ ) {
454                 var d = desc[i];
455                 if( d.item_lang() != lang ) continue;
456                 formats.push( _t_f_2_format(d.item_type(), d.item_form()));
457         }
458
459         formats = uniquify(formats);
460
461         return {
462                 lang : lang,
463                 avail_formats : formats, 
464                 sel_formats : sformats
465         };
466 }
467
468
469
470 function _t_f_2_format(type, form) {
471         if( form == 'd' ) return 'at-d';
472         return (type == 'a' || type == 't') ? 'at' : 
473                 ( type == 'i' || type == 'g' || type == 'j' ) ? type : null;
474 }
475
476 function holdsSetSelectedFormats() {
477
478         var cn = $('holds_alt_formats_row').className;
479         if( cn && cn.match(/hide_me/) ) return;
480
481         var selector = $('hold_alt_form_selector');
482         var vals = getSelectedList(selector);
483
484         if(vals.length == 0) return;
485
486         var fstring = "";
487
488         if( contains(vals, 'at-d') ) {
489                 if( contains(vals, 'at') )
490                         fstring = 'at';
491                 else 
492                         fstring = 'at-d';
493         } else {
494                 if( contains(vals, 'at') )
495                         fstring = 'at';
496         }
497
498         for( var i = 0; i < vals.length; i++ ) {
499                 var val = vals[i];
500                 if( !val.match(/at/) ) fstring = val + fstring;
501         }
502
503         if( holdArgs.language ) {
504                 if( fstring.match(/-/) )
505                         fstring = fstring + '-' + holdArgs.language;
506                 else
507                         fstring = fstring + '--' + holdArgs.language;
508         }
509
510
511         return fstring;
512 }
513
514
515 function holdsCheckPossibility(pickuplib) {
516         var rec = holdArgs.record;
517         var type = holdArgs.type;
518         var req = new Request(CHECK_HOLD_POSSIBLE, G.user.session, 
519                         { titleid : rec, patronid : G.user.id(), depth : 0, pickup_lib : pickuplib } );
520         req.send(true);
521         return req.result();
522 }
523
524
525 function holdsBuildOrgSelector(node) {
526
527         if(!node) node = globalOrgTree;
528
529         var selector = $('holds_org_selector');
530         var index = selector.options.length;
531
532         var type = findOrgType(node.ou_type());
533         var indent = type.depth() - 1;
534         var opt = setSelectorVal( selector, index, node.name(), node.id(), null, indent );
535         if(!type.can_have_users()) {
536                 opt.disabled = true;
537                 addCSSClass(opt, 'disabled_option');
538         }
539         
540         if( node.id() == holdArgs.recipient.home_ou() ) {
541                 selector.selectedIndex = index;
542                 selector.options[index].selected = true;        
543         }
544
545         for( var i in node.children() ) {
546                 var child = node.children()[i];
547                 if(child) holdsBuildOrgSelector(child);
548         }
549 }
550
551 function holdsBuildHoldFromWindow() {
552
553         var org = getSelectorVal($('holds_org_selector'));
554         var node = findOrgUnit(org);
555         var ntype = findOrgType(node.ou_type());
556         if(!ntype.can_have_users()) {
557                 alertId('holds_pick_good_org');
558                 return;
559         }
560
561         var hold = new ahr();
562         if(holdArgs.editHold) {
563                 hold = holdArgs.editHold;
564                 holdArgs.editHold = null;
565         }
566
567         if( $('holds_enable_phone').checked ) {
568                 var phone = $('holds_phone').value;
569                 if( !phone || !phone.match(REGEX_PHONE) ) {
570                         alert($('holds_bad_phone').innerHTML);
571                         return null;
572                 }
573                 hold.phone_notify(phone);
574
575         } else {
576                 hold.phone_notify("");
577         }
578
579         if( $('holds_enable_email').checked ) 
580                 hold.email_notify(1);
581         else
582                 hold.email_notify(0);
583
584         var target;
585
586         switch(holdArgs.type) {
587                 case 'M':
588                         target = holdArgs.metarecord; break;
589                 case 'T':
590                         target = holdArgs.record; break;
591                 case 'V':
592                         target = holdArgs.volume; break;
593                 case 'C':
594                         target = holdArgs.copy; break;
595         }
596
597
598
599         hold.pickup_lib(org); 
600         hold.request_lib(org); 
601         hold.requestor(holdArgs.requestor.id());
602         hold.usr(holdArgs.recipient.id());
603         hold.target(target);
604         hold.hold_type(holdArgs.type);
605
606         //check for alternate hold formats 
607         var fstring = holdsSetSelectedFormats();
608         if(fstring) { 
609                 hold.hold_type('M'); 
610                 hold.holdable_formats(fstring);
611                 hold.target(holdArgs.metarecord);
612         }
613
614         //alert(fstring); return;
615
616         if(isXUL())             
617                 hold.selection_depth(getSelectorVal($('holds_depth_selector')));
618
619         return hold;
620 }
621         
622 function holdsPlaceHold(hold) {
623
624         if(!hold) return;
625
626         swapCanvas($('check_holds_box'));
627
628         if( holdArgs.type == 'M' || holdArgs.type == 'T' ) {
629                 if( ! holdsCheckPossibility(hold.pickup_lib() ) ) {
630                         alert($('hold_not_allowed').innerHTML);
631                         swapCanvas($('holds_box'));
632                         return;
633                 }
634         }
635
636         var req = new Request( CREATE_HOLD, holdArgs.requestor.session, hold );
637         req.send(true);
638         var res = req.result();
639
640         if( res == '1' ) alert($('holds_success').innerHTML);
641         else alert($('holds_failure').innerHTML);
642         
643         showCanvas();
644
645         holdArgs = null;
646         runEvt('common', 'holdUpdated');
647 }
648
649 function holdsCancel(holdid, user) {
650         if(!user) user = G.user;
651         var req = new Request(CANCEL_HOLD, user.session, holdid);
652         req.send(true);
653         return req.result();
654         runEvt('common', 'holdUpdated');
655 }
656
657 function holdsUpdate(hold, user) {
658         if(!user) user = G.user;
659         var req = new Request(UPDATE_HOLD, user.session, hold);
660         req.send(true);
661         var x = req.result(); // cause an exception if there is one 
662         runEvt('common', 'holdUpdated');
663 }
664
665