]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/opac/skin/default/js/holds.js
more metarecord holds work
[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
206         if(args.recordObject) 
207                 args.record = args.recordObject.doc_id();
208         else 
209                 args.recordObject = findRecord( args.record, 'T' );
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 function _h_set_rec_descriptors(args, doneCallback) {
218
219         /* grab the list of record desciptors attached to this records metarecord */
220         if( ! args.recordDescriptors )  {
221                 var params = { record: args.record };
222
223                 if( ! args.record ) {
224                         if( args.metarecord )
225                                 params = { metarecord : args.metarecord };
226                         else 
227                                 params = { metarecord : args.metarecordObject.id() };
228                 }
229
230                 var req = new Request(FETCH_MR_DESCRIPTORS, params );
231                 req.callback(
232                         function(r) {
233                                 var data = r.getResultObject();
234                                 args.recordDescriptors = data.descriptors;
235                                 args.metarecord = data.metarecord;
236                                 if(doneCallback) doneCallback(args);
237                         }
238                 );
239                 req.send();
240
241         } else {
242                 if(doneCallback) doneCallback(args);
243         }
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, function(){__holdsDrawWindow();});
254 }
255
256 function __holdsDrawWindow() {
257
258         var rec = holdArgs.recordObject;
259         var vol = holdArgs.volumeObject;
260         var copy = holdArgs.copyObject;
261
262         if(!holdsOrgSelectorBuilt) {
263                 holdsBuildOrgSelector(null,0);
264                 holdsOrgSelectorBuilt = true;
265         }
266
267         if(isXUL()) {
268                 var dsel = $('holds_depth_selector');
269                 unHideMe($('holds_depth_selector_row'));
270                 if(dsel.getElementsByTagName('option').length == 0) {
271                         var types = globalOrgTypes;
272                         var depth = findOrgDepth(G.user.ws_ou());
273                         iterate(types, 
274                                 function(t) {
275                                         if(t.depth() > depth) return;
276                                         insertSelectorVal(dsel, -1, t.opac_label(), t.depth());
277                                 }
278                         );
279                 }
280         }
281
282         appendClear($('holds_recipient'), text(
283                 holdArgs.recipient.family_name() + ', ' +  
284                         holdArgs.recipient.first_given_name()));
285         appendClear($('holds_title'), text(rec.title()));
286         appendClear($('holds_author'), text(rec.author()));
287
288         if( holdArgs.type == 'V' || holdArgs.type == 'C' ) {
289
290                 unHideMe($('holds_type_row'));
291                 unHideMe($('holds_cn_row'));
292                 appendClear($('holds_cn'), text(holdArgs.volumeObject.label()));
293
294                 if( holdArgs.type == 'V'  ) {
295                         unHideMe($('holds_is_cn'));
296                         hideMe($('holds_is_copy'));
297
298                 } else {
299                         hideMe($('holds_is_cn'));
300                         unHideMe($('holds_is_copy'));
301                         unHideMe($('holds_copy_row'));
302                         appendClear($('holds_copy'), text(holdArgs.copyObject.barcode()));
303                 }
304
305         } else {
306                 hideMe($('holds_type_row'));
307                 hideMe($('holds_copy_row'));
308                 hideMe($('holds_cn_row'));
309         }
310
311         removeChildren($('holds_format'));
312         var formats = rec.types_of_resource();
313
314         if( holdArgs.type == 'M' ) {
315                 var data = holdsParseMRFormats(holdArgs.editHold.holdable_formats());
316                 formats = data.formats;
317         }
318
319
320         for( var i in formats ) {
321                 var res = formats[i];
322                 var img = elem("img");
323                 setResourcePic(img, res);
324                 $('holds_format').appendChild(text(' '+res+' '));
325                 $('holds_format').appendChild(img);
326                 $('holds_format').appendChild(text(' '));
327         }
328
329
330         $('holds_phone').value = holdArgs.recipient.day_phone();
331         appendClear( $('holds_email'), text(holdArgs.recipient.email()));
332
333         var pref = G.user.prefs[PREF_HOLD_NOTIFY];
334
335         if(pref) {
336                 if( ! pref.match(/email/i) ) 
337                         $('holds_enable_email').checked = false;
338
339                 if( ! pref.match(/phone/i) ) {
340                         $('holds_phone').disabled = true;
341                         $('holds_enable_phone').checked = false;
342                 }
343         }
344
345         appendClear($('holds_physical_desc'), text(rec.physical_description()));
346
347         if(holdArgs.type == 'M') hideMe($('hold_physical_desc_row'));
348
349         holdsSetFormatSelector();
350 }
351
352 function holdsParseMRFormats(str) {
353         var data = str.split(/-/);      
354
355         var formats = [];
356         for( var i = 0; i < data[0].length; i++ ) 
357                 formats.push(MARCFormatToMods(data[0].charAt(i)));
358         
359         formats = uniquify(formats);
360
361         return {
362                 formats         : formats,
363                 lang                    : data[2],
364                 largeprint      : data[1],      
365         }
366 }
367
368
369 function holdsSetFormatSelector() {
370         var type = holdArgs.type;
371         if( type == 'C' || type == 'V' ) return;
372
373         var data                                = holdsGetFormats();
374         var avail_formats       = data.avail_formats;
375         var sel_formats = data.sel_formats;
376         holdArgs.language = data.lang;
377
378         if( avail_formats.length > 1 ) {
379
380                 unHideMe($('holds_alt_formats_row'));
381                 var selector = $('hold_alt_form_selector');
382
383                 for( var i = 0; i < avail_formats.length; i++ ) {
384                         var form = avail_formats[i];
385                         if( contains(sel_formats, form) ) continue;
386                         unHideMe(findSelectorOptByValue(selector, form));
387                 }
388         }
389 }
390
391
392 function holdsGetFormats() {
393
394         var lang;
395         var formats = [];
396         var sformats = []; /* selected formats */
397
398         var type = holdArgs.type;
399         var desc = holdArgs.recordDescriptors;
400         var rec = holdArgs.record;
401         var mrec = holdArgs.metarecord;
402
403         if( type == 'T' ) {
404
405                 for( var i = 0; i < desc.length; i++ ) {
406                         var d = desc[i];
407                         if( d.record() == holdArgs.record ) {
408                                 lang = d.item_lang();
409                                 holdArgs.myFormat =  _t_f_2_format(d.item_type(), d.item_form());
410                                 sformats.push(holdArgs.myFormat);
411                                 break;
412                         }
413                 }
414         }
415
416         for( var i = 0; i < desc.length; i++ ) {
417                 var d = desc[i];
418                 if( d.item_lang() != lang ) continue;
419                 formats.push( _t_f_2_format(d.item_type(), d.item_form()));
420         }
421
422         formats = uniquify(formats);
423
424         return {
425                 lang : lang,
426                 avail_formats : formats, 
427                 sel_formats : sformats,
428         }
429 }
430
431
432
433 function _t_f_2_format(type, form) {
434         if( form == 'd' ) return 'at-d';
435         return (type == 'a' || type == 't') ? 'at' : 
436                 ( type == 'i' || type == 'g' || type == 'j' ) ? type : null;
437 }
438
439 function holdsSetSelectedFormats() {
440
441         var cn = $('holds_alt_formats_row').className;
442         if( cn && cn.match(/hide_me/) ) return;
443
444         var selector = $('hold_alt_form_selector');
445         var vals = getSelectedList(selector);
446
447         if(vals.length == 0) return;
448
449         if( holdArgs.type == 'T' ) 
450                 vals.push(holdArgs.myFormat);
451
452         var fstring = "";
453
454         if( contains(vals, 'at-d') ) {
455                 if( contains(vals, 'at') )
456                         fstring = 'at';
457                 else 
458                         fstring = 'at-d';
459         } else {
460                 if( contains(vals, 'at') )
461                         fstring = 'at';
462         }
463
464         for( var i = 0; i < vals.length; i++ ) {
465                 var val = vals[i];
466                 if( !val.match(/at/) ) fstring = val + fstring;
467         }
468
469         if( holdArgs.language ) {
470                 if( fstring.match(/-/) )
471                         fstring = fstring + '-' + holdArgs.language;
472                 else
473                         fstring = fstring + '--' + holdArgs.language;
474         }
475
476
477         return fstring;
478 }
479
480
481 function holdsCheckPossibility(pickuplib) {
482         var rec = holdArgs.record;
483         var type = holdArgs.type;
484         var req = new Request(CHECK_HOLD_POSSIBLE, G.user.session, 
485                         { titleid : rec, patronid : G.user.id(), depth : 0, pickup_lib : pickuplib } );
486         req.send(true);
487         return req.result();
488 }
489
490
491 function holdsBuildOrgSelector(node) {
492
493         if(!node) node = globalOrgTree;
494
495         var selector = $('holds_org_selector');
496         var index = selector.options.length;
497
498         var type = findOrgType(node.ou_type());
499         var indent = type.depth() - 1;
500         var opt = setSelectorVal( selector, index, node.name(), node.id(), null, indent );
501         if(!type.can_have_vols()) opt.disabled = true;
502         
503         if( node.id() == holdArgs.recipient.home_ou() ) {
504                 selector.selectedIndex = index;
505                 selector.options[index].selected = true;        
506         }
507
508         for( var i in node.children() ) {
509                 var child = node.children()[i];
510                 if(child) holdsBuildOrgSelector(child);
511         }
512 }
513
514 function holdsBuildHoldFromWindow() {
515
516         var org = $('holds_org_selector').options[
517                 $('holds_org_selector').selectedIndex].value;
518
519         var hold = new ahr();
520         if(holdArgs.editHold) {
521                 hold = holdArgs.editHold;
522                 holdArgs.editHold = null;
523         }
524
525         if( $('holds_enable_phone').checked ) {
526                 var phone = $('holds_phone').value;
527                 if( !phone || !phone.match(REGEX_PHONE) ) {
528                         alert($('holds_bad_phone').innerHTML);
529                         return null;
530                 }
531                 hold.phone_notify(phone);
532
533         } else {
534                 hold.phone_notify("");
535         }
536
537         if( $('holds_enable_email').checked ) 
538                 hold.email_notify(1);
539         else
540                 hold.email_notify(0);
541
542         var target;
543
544         switch(holdArgs.type) {
545                 case 'M':
546                         target = holdArgs.metarecord; break;
547                 case 'T':
548                         target = holdArgs.record; break;
549                 case 'V':
550                         target = holdArgs.volume; break;
551                 case 'C':
552                         target = holdArgs.copy; break;
553         }
554
555
556
557         hold.pickup_lib(org); 
558         hold.request_lib(org); 
559         hold.requestor(holdArgs.requestor.id());
560         hold.usr(holdArgs.recipient.id());
561         hold.target(target);
562         hold.hold_type(holdArgs.type);
563
564         /* check for alternate hold formats */
565         var fstring = holdsSetSelectedFormats();
566         if(fstring) { 
567                 hold.hold_type('M'); 
568                 hold.holdable_formats(fstring);
569                 hold.target(holdArgs.metarecord);
570         }
571
572         if(isXUL())             
573                 hold.selection_depth(getSelectorVal($('holds_depth_selector')));
574
575         return hold;
576 }
577         
578 function holdsPlaceHold(hold) {
579
580         if(!hold) return;
581
582         swapCanvas($('check_holds_box'));
583
584         if( holdArgs.type == 'M' || holdArgs.type == 'T' ) {
585                 if( ! holdsCheckPossibility(hold.pickup_lib() ) ) {
586                         alert($('hold_not_allowed').innerHTML);
587                         swapCanvas($('holds_box'));
588                         return;
589                 }
590         }
591
592         var req = new Request( CREATE_HOLD, holdArgs.requestor.session, hold );
593         req.send(true);
594         var res = req.result();
595
596         if( res == '1' ) alert($('holds_success').innerHTML);
597         else alert($('holds_failure').innerHTML);
598         
599         showCanvas();
600
601         holdArgs = null;
602         runEvt('common', 'holdUpdated');
603 }
604
605 function holdsCancel(holdid, user) {
606         if(!user) user = G.user;
607         var req = new Request(CANCEL_HOLD, user.session, holdid);
608         req.send(true);
609         return req.result();
610         runEvt('common', 'holdUpdated');
611 }
612
613 function holdsUpdate(hold, user) {
614         if(!user) user = G.user;
615         var req = new Request(UPDATE_HOLD, user.session, hold);
616         req.send(true);
617         var x = req.result(); /* cause an exception if there is one */
618         runEvt('common', 'holdUpdated');
619 }
620
621
622
623