]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/opac/skin/default/js/holds.js
default pickup_lib is now set to 'origloc' (the original location for the opac)
[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                 var selector = $('holds_org_selector');
284                 var o_loc = findOrgUnit(getOrigLocation());
285                 var t = findOrgType(o_loc.ou_type());
286
287                 if( t.can_have_users() ) 
288                         setSelector(selector, o_loc.id());
289                 else 
290                         setSelector(selector, holdArgs.recipient.home_ou());
291         
292         }
293
294         if(isXUL()) {
295                 var dsel = $('holds_depth_selector');
296                 unHideMe($('holds_depth_selector_row'));
297                 if(dsel.getElementsByTagName('option').length == 0) {
298                         var types = globalOrgTypes;
299                         var depth = findOrgDepth(G.user.ws_ou());
300                         iterate(types, 
301                                 function(t) {
302                                         if(t.depth() > depth) return;
303                                         insertSelectorVal(dsel, -1, t.opac_label(), t.depth());
304                                 }
305                         );
306                 }
307         }
308
309         appendClear($('holds_recipient'), text(
310                 holdArgs.recipient.family_name() + ', ' +  
311                         holdArgs.recipient.first_given_name()));
312         appendClear($('holds_title'), text(rec.title()));
313         appendClear($('holds_author'), text(rec.author()));
314
315         if( holdArgs.type == 'V' || holdArgs.type == 'C' ) {
316
317                 unHideMe($('holds_type_row'));
318                 unHideMe($('holds_cn_row'));
319                 appendClear($('holds_cn'), text(holdArgs.volumeObject.label()));
320
321                 if( holdArgs.type == 'V'  ) {
322                         unHideMe($('holds_is_cn'));
323                         hideMe($('holds_is_copy'));
324
325                 } else {
326                         hideMe($('holds_is_cn'));
327                         unHideMe($('holds_is_copy'));
328                         unHideMe($('holds_copy_row'));
329                         appendClear($('holds_copy'), text(holdArgs.copyObject.barcode()));
330                 }
331
332         } else {
333                 hideMe($('holds_type_row'));
334                 hideMe($('holds_copy_row'));
335                 hideMe($('holds_cn_row'));
336         }
337
338         removeChildren($('holds_format'));
339
340         var mods_formats = rec.types_of_resource();
341         var formats;
342
343         if(holdArgs.recordDescriptors)
344                 formats = holdArgs.recordDescriptors[0].item_type();
345
346         if( holdArgs.type == 'T' ) {
347                 var desc = grep( holdArgs.recordDescriptors,
348                         function(i) {
349                                 return (i.record() == holdArgs.record); 
350                         }
351                 );
352                 formats = desc[0].item_type();
353         }
354
355         if( holdArgs.type == 'M' ) {
356                 var data = holdsParseMRFormats(holdArgs.editHold.holdable_formats());
357                 mods_formats = data.mods_formats;
358                 formats = data.formats;
359         }
360
361
362         for( var i in mods_formats ) {
363                 var res = mods_formats[i];
364                 var img = elem("img");
365                 setResourcePic(img, res);
366                 $('holds_format').appendChild(img);
367                 if(formats)
368                         $('holds_format').appendChild(text(' '+ MARCTypeToFriendly(formats[i]) +' '));
369                 else
370                         $('holds_format').appendChild(text(' '+ mods_formats[i] +' '));
371                 $('holds_format').appendChild(elem('br'));
372         }
373
374
375         $('holds_phone').value = holdArgs.recipient.day_phone();
376         appendClear( $('holds_email'), text(holdArgs.recipient.email()));
377
378         var pref = G.user.prefs[PREF_HOLD_NOTIFY];
379
380         if(pref) {
381                 if( ! pref.match(/email/i) ) 
382                         $('holds_enable_email').checked = false;
383
384                 if( ! pref.match(/phone/i) ) {
385                         $('holds_phone').disabled = true;
386                         $('holds_enable_phone').checked = false;
387                 }
388         }
389
390         appendClear($('holds_physical_desc'), text(rec.physical_description()));
391
392         if(holdArgs.type == 'M') hideMe($('hold_physical_desc_row'));
393
394         holdsSetFormatSelector();
395 }
396
397 function holdsParseMRFormats(str) {
398         var data = str.split(/-/);      
399
400         var formats = [];
401         var mods_formats = [];
402
403         for( var i = 0; i < data[0].length; i++ ) {
404                 formats.push( data[0].charAt(i) );
405                 mods_formats.push( MARCFormatToMods( formats[i] ) );
406         }
407         
408         formats = uniquify(formats);
409         mods_formats = uniquify(mods_formats);
410
411         return {
412                 formats                 : formats,
413                 mods_formats    : mods_formats,
414                 lang                            : data[2],
415                 largeprint              : data[1]
416         };
417 }
418
419
420 function holdsSetFormatSelector() {
421         var type = holdArgs.type;
422         if( type == 'C' || type == 'V' || holdArgs.editHold ) return;
423
424         var data                                = holdsGetFormats();
425         var avail_formats       = data.avail_formats;
426         var sel_formats = data.sel_formats;
427         holdArgs.language = data.lang;
428
429         unHideMe($('holds_alt_formats_row_extras'));
430         var selector = $('hold_alt_form_selector');
431
432         for( var i = 0; i < avail_formats.length; i++ ) {
433                 var form = avail_formats[i];
434                 unHideMe(findSelectorOptByValue(selector, form));
435         }
436 }
437
438
439 function holdsGetFormats() {
440
441         var lang;
442         var formats = [];
443         var sformats = []; // selected formats 
444
445         var type = holdArgs.type;
446         var desc = holdArgs.recordDescriptors;
447         var rec = holdArgs.record;
448         var mrec = holdArgs.metarecord;
449
450         if( type == 'T' ) {
451
452                 for( var i = 0; i < desc.length; i++ ) {
453                         var d = desc[i];
454                         if( d.record() == holdArgs.record ) {
455                                 lang = d.item_lang();
456                                 holdArgs.myFormat =  _t_f_2_format(d.item_type(), d.item_form());
457                                 sformats.push(holdArgs.myFormat);
458                                 break;
459                         }
460                 }
461         }
462
463         for( var i = 0; i < desc.length; i++ ) {
464                 var d = desc[i];
465                 if( d.item_lang() != lang ) continue;
466                 formats.push( _t_f_2_format(d.item_type(), d.item_form()));
467         }
468
469         formats = uniquify(formats);
470
471         return {
472                 lang : lang,
473                 avail_formats : formats, 
474                 sel_formats : sformats
475         };
476 }
477
478
479
480 function _t_f_2_format(type, form) {
481         if( form == 'd' ) return 'at-d';
482         return (type == 'a' || type == 't') ? 'at' : 
483                 ( type == 'i' || type == 'g' || type == 'j' ) ? type : null;
484 }
485
486 function holdsSetSelectedFormats() {
487
488         var cn = $('holds_alt_formats_row').className;
489         if( cn && cn.match(/hide_me/) ) return;
490
491         var selector = $('hold_alt_form_selector');
492         var vals = getSelectedList(selector);
493
494         if(vals.length == 0) return;
495
496         var fstring = "";
497
498         if( contains(vals, 'at-d') ) {
499                 if( contains(vals, 'at') )
500                         fstring = 'at';
501                 else 
502                         fstring = 'at-d';
503         } else {
504                 if( contains(vals, 'at') )
505                         fstring = 'at';
506         }
507
508         for( var i = 0; i < vals.length; i++ ) {
509                 var val = vals[i];
510                 if( !val.match(/at/) ) fstring = val + fstring;
511         }
512
513         if( holdArgs.language ) {
514                 if( fstring.match(/-/) )
515                         fstring = fstring + '-' + holdArgs.language;
516                 else
517                         fstring = fstring + '--' + holdArgs.language;
518         }
519
520
521         return fstring;
522 }
523
524
525 function holdsCheckPossibility(pickuplib) {
526         var rec = holdArgs.record;
527         var type = holdArgs.type;
528         var req = new Request(CHECK_HOLD_POSSIBLE, G.user.session, 
529                         { titleid : rec, patronid : G.user.id(), depth : 0, pickup_lib : pickuplib } );
530         req.send(true);
531         return req.result();
532 }
533
534
535 function holdsBuildOrgSelector(node) {
536
537         if(!node) node = globalOrgTree;
538
539         var selector = $('holds_org_selector');
540         var index = selector.options.length;
541
542         var type = findOrgType(node.ou_type());
543         var indent = type.depth() - 1;
544         var opt = setSelectorVal( selector, index, node.name(), node.id(), null, indent );
545         if(!type.can_have_users()) {
546                 opt.disabled = true;
547                 addCSSClass(opt, 'disabled_option');
548         }
549         
550         for( var i in node.children() ) {
551                 var child = node.children()[i];
552                 if(child) holdsBuildOrgSelector(child);
553         }
554 }
555
556 function holdsBuildHoldFromWindow() {
557
558         var org = getSelectorVal($('holds_org_selector'));
559         var node = findOrgUnit(org);
560         var ntype = findOrgType(node.ou_type());
561         if(!ntype.can_have_users()) {
562                 alertId('holds_pick_good_org');
563                 return;
564         }
565
566         var hold = new ahr();
567         if(holdArgs.editHold) {
568                 hold = holdArgs.editHold;
569                 holdArgs.editHold = null;
570         }
571
572         if( $('holds_enable_phone').checked ) {
573                 var phone = $('holds_phone').value;
574                 if( !phone || !phone.match(REGEX_PHONE) ) {
575                         alert($('holds_bad_phone').innerHTML);
576                         return null;
577                 }
578                 hold.phone_notify(phone);
579
580         } else {
581                 hold.phone_notify("");
582         }
583
584         if( $('holds_enable_email').checked ) 
585                 hold.email_notify(1);
586         else
587                 hold.email_notify(0);
588
589         var target;
590
591         switch(holdArgs.type) {
592                 case 'M':
593                         target = holdArgs.metarecord; break;
594                 case 'T':
595                         target = holdArgs.record; break;
596                 case 'V':
597                         target = holdArgs.volume; break;
598                 case 'C':
599                         target = holdArgs.copy; break;
600         }
601
602
603
604         hold.pickup_lib(org); 
605         hold.request_lib(org); 
606         hold.requestor(holdArgs.requestor.id());
607         hold.usr(holdArgs.recipient.id());
608         hold.target(target);
609         hold.hold_type(holdArgs.type);
610
611         //check for alternate hold formats 
612         var fstring = holdsSetSelectedFormats();
613         if(fstring) { 
614                 hold.hold_type('M'); 
615                 hold.holdable_formats(fstring);
616                 hold.target(holdArgs.metarecord);
617         }
618
619         //alert(fstring); return;
620
621         if(isXUL())             
622                 hold.selection_depth(getSelectorVal($('holds_depth_selector')));
623
624         return hold;
625 }
626         
627 function holdsPlaceHold(hold) {
628
629         if(!hold) return;
630
631         swapCanvas($('check_holds_box'));
632
633         if( holdArgs.type == 'M' || holdArgs.type == 'T' ) {
634                 if( ! holdsCheckPossibility(hold.pickup_lib() ) ) {
635                         alert($('hold_not_allowed').innerHTML);
636                         swapCanvas($('holds_box'));
637                         return;
638                 }
639         }
640
641         var req = new Request( CREATE_HOLD, holdArgs.requestor.session, hold );
642         req.send(true);
643         var res = req.result();
644
645         if( res == '1' ) alert($('holds_success').innerHTML);
646         else alert($('holds_failure').innerHTML);
647         
648         showCanvas();
649
650         holdArgs = null;
651         runEvt('common', 'holdUpdated');
652 }
653
654 function holdsCancel(holdid, user) {
655         if(!user) user = G.user;
656         var req = new Request(CANCEL_HOLD, user.session, holdid);
657         req.send(true);
658         return req.result();
659         runEvt('common', 'holdUpdated');
660 }
661
662 function holdsUpdate(hold, user) {
663         if(!user) user = G.user;
664         var req = new Request(UPDATE_HOLD, user.session, hold);
665         req.send(true);
666         var x = req.result(); // cause an exception if there is one 
667         runEvt('common', 'holdUpdated');
668 }
669
670