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