1 var holdsOrgSelectorBuilt = false;
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
12 var noEmailMessageXUL;
14 function holdsHandleStaff() {
15 swapCanvas($('xulholds_box'));
16 $('xul_recipient_barcode').focus();
17 $('xul_recipient_barcode').onkeypress = function(evt)
18 {if(userPressedEnter(evt)) { _holdsHandleStaff(); } };
19 $('xul_recipient_barcode_submit').onclick = _holdsHandleStaff;
20 $('xul_recipient_me').onclick = _holdsHandleStaffMe;
22 $('xul_recipient_barcode').onkeyup = function(evt) {
23 if($('xul_recipient_barcode').value == '')
24 $('xul_recipient_me').disabled = false;
26 $('xul_recipient_me').disabled = true;
30 $('holds_frozen_thaw_input').onchange =
31 function(){holdsVerifyThawDateUI('holds_frozen_thaw_input');}
32 $('holds_frozen_thaw_input').onkeyup =
33 function(){holdsVerifyThawDateUI('holds_frozen_thaw_input');}
35 function _holdsHandleStaffMe() {
36 holdArgs.recipient = G.user;
40 function _holdsHandleStaff() {
41 var barcode = $('xul_recipient_barcode').value;
42 var user = grabUserByBarcode( G.user.session, barcode );
45 if(evt = checkILSEvent(user)) {
50 if(!barcode || !user) {
51 alertId('holds_invalid_recipient', barcode);
55 holdArgs.recipient = user;
62 * record, volume, copy (ids)
63 * request, recipient, editHold (objects)
66 function holdsDrawEditor(args) {
68 holdArgs = (args) ? args : holdArgs;
71 noEmailMessage = $('holds_email').removeChild($('holds.no_email'));
73 if(!noEmailMessageXUL)
74 noEmailMessageXUL = $('holds_email').removeChild($('holds.no_email.xul'));
76 if(isXUL() && holdArgs.recipient == null
77 && holdArgs.editHold == null) {
82 if(!holdArgs.recipient) holdArgs.recipient = G.user;
83 if(!holdArgs.requestor) holdArgs.requestor = G.user;
85 if(!(holdArgs.requestor && holdArgs.requestor.session)) {
86 detachAllEvt('common','locationChanged');
87 attachEvt('common','loggedIn', holdsDrawEditor)
92 if(holdArgs.editHold) // flesh the args with the existing hold
93 holdArgsFromHold(holdArgs.editHold, holdArgs);
99 // updates the edit window with the existing hold's data
100 function _holdsUpdateEditHold() {
102 var hold = holdArgs.editHold;
103 var status = holdArgs.status;
105 var orgsel = $('holds_org_selector');
106 var frozenbox = $('holds_frozen_chkbox');
108 setSelector(orgsel, hold.pickup_lib());
110 if( hold.capture_time() || status > 2 ) {
111 //orgsel.disabled = true;
112 frozenbox.disabled = true;
113 $('holds_frozen_thaw_input').disabled = true;
116 orgsel.disabled = false;
117 frozenbox.disabled = false;
121 $('holds_submit').onclick = holdsEditHold;
122 $('holds_update').onclick = holdsEditHold;
124 if(hold.phone_notify()) {
125 $('holds_enable_phone').checked = true;
126 $('holds_phone').value = hold.phone_notify();
129 $('holds_phone').disabled = true;
130 $('holds_enable_phone').checked = false;
133 if(isTrue(hold.email_notify())) {
134 $('holds_enable_email').checked = true;
137 $('holds_enable_email').checked = false;
140 /* populate the hold freezing info */
141 if(!frozenbox.disabled && isTrue(hold.frozen())) {
142 frozenbox.checked = true;
143 unHideMe($('hold_frozen_thaw_row'));
144 if(hold.thaw_date()) {
145 dijit.byId('holds_frozen_thaw_input').setValue(hold.thaw_date());
147 dijit.byId('holds_frozen_thaw_input').setValue('');
150 frozenbox.checked = false;
151 dijit.byId('holds_frozen_thaw_input').setValue('');
152 hideMe($('hold_frozen_thaw_row'));
156 function holdsEditHold() {
157 var hold = holdsBuildHoldFromWindow();
161 if(holdArgs.onComplete)
162 holdArgs.onComplete(hold);
165 function holdArgsFromHold(hold, oargs) {
166 var args = (oargs) ? oargs : {};
167 args.type = hold.hold_type();
168 var target = hold.target();
172 args.metarecord = target;
175 args.record = target;
178 args.volume = target;
187 function holdFetchObjects(hold, doneCallback) {
189 var args = (hold) ? holdArgsFromHold(hold) : holdArgs;
191 var type = args.type;
195 if( args.copyObject ) {
197 args.copy = args.copyObject.id();
198 args.volume = args.copyObject.call_number();
199 _h_set_vol(args, doneCallback);
202 var creq = new Request(FETCH_COPY, args.copy);
206 var cp = r.getResultObject();
207 args.copyObject = cp;
208 args.volume = args.copyObject.call_number();
209 _h_set_vol(args, doneCallback);
216 _h_set_vol(args, doneCallback);
220 _h_set_rec(args, doneCallback);
222 _h_set_rec_descriptors(args, doneCallback);
230 function _h_set_vol(args, doneCallback) {
232 if( args.volumeObject ) {
233 args.volume = args.volumeObject.id();
234 args.record = args.volumeObject.record();
235 _h_set_rec(args, doneCallback);
239 var vreq = new Request(FETCH_VOLUME, args.volume);
242 var vol = r.getResultObject();
243 args.volumeObject = vol;
244 args.record = vol.record();
245 _h_set_rec(args, doneCallback);
252 function _h_set_rec(args, doneCallback) {
254 if(args.recordObject)
255 args.record = args.recordObject.doc_id();
257 args.recordObject = findRecord( args.record, 'T' );
259 if( args.type == 'T' || args.type == 'M' )
260 _h_set_rec_descriptors(args, doneCallback);
262 if(doneCallback) doneCallback(args);
266 function _h_set_rec_descriptors(args, doneCallback) {
268 // grab the list of record desciptors attached to this records metarecord
269 if( ! args.recordDescriptors ) {
270 var params = { record: args.record };
272 if( ! args.record ) {
273 if( args.metarecord )
274 params = { metarecord : args.metarecord };
276 params = { metarecord : args.metarecordObject.doc_id() };
279 var req = new Request(FETCH_MR_DESCRIPTORS, params );
282 var data = r.getResultObject();
283 args.recordDescriptors = data.descriptors;
284 args.metarecord = data.metarecord;
285 if( args.type == 'M' && ! args.metarecordObject)
286 args.metarecordObject = findRecord(args.metarecord, 'M');
288 if(doneCallback) doneCallback(args);
294 if(doneCallback) doneCallback(args);
302 function holdsDrawWindow() {
303 swapCanvas($('holds_box'));
304 $('holds_cancel').onclick = function(){ runEvt('common', 'holdUpdateCanceled'), showCanvas() };
305 $('holds_submit').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
306 $('holds_update').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
307 holdFetchObjects(null,
311 if(holdArgs.editHold) {
312 hideMe($('holds_submit'));
313 unHideMe($('holds_update'));
314 var req = new Request(FETCH_HOLD_STATUS,
315 G.user.session, holdArgs.editHold.id());
317 holdArgs.status = req.result();
318 _holdsUpdateEditHold();
324 function __holdsDrawWindow() {
326 var rec = holdArgs.recordObject;
327 var vol = holdArgs.volumeObject;
328 var copy = holdArgs.copyObject;
329 var mr = holdArgs.metarecordObject;
331 rec = (rec) ? rec : mr;
333 if(!holdsOrgSelectorBuilt) {
334 holdsBuildOrgSelector(null,0);
335 holdsOrgSelectorBuilt = true;
336 var selector = $('holds_org_selector');
339 var o_loc = findOrgUnit(getOrigLocation());
340 var t = findOrgType(o_loc.ou_type());
341 if( t.can_have_users() )
342 setSelector(selector, o_loc.id());
346 setSelector(selector, holdArgs.recipient.home_ou());
352 var dsel = $('holds_depth_selector');
353 unHideMe($('holds_depth_selector_row'));
354 if(dsel.getElementsByTagName('option').length == 0) {
355 var types = globalOrgTypes;
356 var depth = findOrgDepth(G.user.ws_ou());
359 if(t.depth() > depth) return;
360 insertSelectorVal(dsel, -1, t.opac_label(), t.depth());
367 appendClear($('holds_recipient'), text(
368 holdArgs.recipient.family_name() + ', ' +
369 holdArgs.recipient.first_given_name()));
370 appendClear($('holds_title'), text(rec.title()));
371 appendClear($('holds_author'), text(rec.author()));
373 if( holdArgs.type == 'V' || holdArgs.type == 'C' ) {
375 unHideMe($('holds_type_row'));
376 unHideMe($('holds_cn_row'));
377 appendClear($('holds_cn'), text(holdArgs.volumeObject.label()));
379 if( holdArgs.type == 'V' ) {
380 unHideMe($('holds_is_cn'));
381 hideMe($('holds_is_copy'));
384 hideMe($('holds_is_cn'));
385 unHideMe($('holds_is_copy'));
386 unHideMe($('holds_copy_row'));
387 appendClear($('holds_copy'), text(holdArgs.copyObject.barcode()));
391 hideMe($('holds_type_row'));
392 hideMe($('holds_copy_row'));
393 hideMe($('holds_cn_row'));
396 removeChildren($('holds_format'));
398 var mods_formats = rec.types_of_resource();
401 if(holdArgs.recordDescriptors)
402 formats = holdArgs.recordDescriptors[0].item_type();
404 if( holdArgs.type == 'T' ) {
405 var desc = grep( holdArgs.recordDescriptors,
407 return (i.record() == holdArgs.record);
410 formats = desc[0].item_type();
413 if( holdArgs.type == 'M' ) {
414 var data = holdsParseMRFormats(holdArgs.editHold.holdable_formats());
415 mods_formats = data.mods_formats;
416 formats = data.formats;
420 for( var i in mods_formats ) {
421 var res = mods_formats[i];
422 var img = elem("img");
423 setResourcePic(img, res);
424 $('holds_format').appendChild(img);
426 $('holds_format').appendChild(text(' '+ MARCTypeToFriendly(formats[i]) +' '));
428 $('holds_format').appendChild(text(' '+ mods_formats[i] +' '));
429 $('holds_format').appendChild(elem('br'));
433 $('holds_phone').value = holdArgs.recipient.day_phone();
434 appendClear( $('holds_email'), text(holdArgs.recipient.email()));
436 var pref = G.user.prefs[PREF_HOLD_NOTIFY];
439 if( ! pref.match(/email/i) )
440 $('holds_enable_email').checked = false;
442 if( ! pref.match(/phone/i) ) {
443 $('holds_phone').disabled = true;
444 $('holds_enable_phone').checked = false;
448 //if(!G.user.email()) {
449 if(!holdArgs.recipient.email()) {
450 $('holds_enable_email').checked = false;
451 $('holds_enable_email').disabled = true;
454 message = noEmailMessageXUL.cloneNode(true);
455 appendClear($('holds_email'), message);
457 message = noEmailMessage.cloneNode(true);
458 appendClear($('holds_email'), message);
459 $('holds.no_email.my_account').setAttribute('href', buildOPACLink({page:MYOPAC},null,true));
464 if(!$('holds_phone').value)
465 $('holds_enable_phone').checked = false;
467 appendClear($('holds_physical_desc'), text(rec.physical_description()));
469 if(holdArgs.type == 'M') hideMe($('hold_physical_desc_row'));
471 holdsSetFormatSelector();
473 $('holds_frozen_chkbox').checked = false;
474 hideMe($('hold_frozen_thaw_row'));
478 function holdsParseMRFormats(str) {
479 var data = str.split(/-/);
482 var mods_formats = [];
484 for( var i = 0; i < data[0].length; i++ ) {
485 formats.push( data[0].charAt(i) );
486 mods_formats.push( MARCFormatToMods( formats[i] ) );
489 formats = uniquify(formats);
490 mods_formats = uniquify(mods_formats);
494 mods_formats : mods_formats,
501 function holdsSetFormatSelector() {
502 var type = holdArgs.type;
503 if( type == 'C' || type == 'V' || holdArgs.editHold ) return;
505 var data = holdsGetFormats();
506 var avail_formats = data.avail_formats;
507 var sel_formats = data.sel_formats;
508 holdArgs.language = data.lang;
510 unHideMe($('holds_alt_formats_row_extras'));
511 var selector = $('hold_alt_form_selector');
513 for( var i = 0; i < avail_formats.length; i++ ) {
514 var form = avail_formats[i];
515 unHideMe(findSelectorOptByValue(selector, form));
520 function holdsGetFormats() {
524 var sformats = []; // selected formats
526 var type = holdArgs.type;
527 var desc = holdArgs.recordDescriptors;
528 var rec = holdArgs.record;
529 var mrec = holdArgs.metarecord;
533 for( var i = 0; i < desc.length; i++ ) {
535 if( d.record() == holdArgs.record ) {
536 lang = d.item_lang();
537 holdArgs.myFormat = _t_f_2_format(d.item_type(), d.item_form());
538 sformats.push(holdArgs.myFormat);
544 for( var i = 0; i < desc.length; i++ ) {
546 if( d.item_lang() != lang ) continue;
547 formats.push( _t_f_2_format(d.item_type(), d.item_form()));
550 formats = uniquify(formats);
554 avail_formats : formats,
555 sel_formats : sformats
561 function _t_f_2_format(type, form) {
562 if( form == 'd' ) return 'at-d';
563 return (type == 'a' || type == 't') ? 'at' :
564 ( type == 'i' || type == 'g' || type == 'j' ) ? type : null;
567 function holdsSetSelectedFormats() {
569 var cn = $('holds_alt_formats_row').className;
570 if( cn && cn.match(/hide_me/) ) return;
572 var selector = $('hold_alt_form_selector');
573 var vals = getSelectedList(selector);
575 if(vals.length == 0) return;
579 if( contains(vals, 'at-d') ) {
580 if( contains(vals, 'at') )
585 if( contains(vals, 'at') )
589 for( var i = 0; i < vals.length; i++ ) {
591 if( !val.match(/at/) ) fstring = val + fstring;
594 if( holdArgs.language ) {
595 if( fstring.match(/-/) )
596 fstring = fstring + '-' + holdArgs.language;
598 fstring = fstring + '--' + holdArgs.language;
606 function holdsCheckPossibility(pickuplib, hold, recurse) {
609 titleid : holdArgs.record,
610 volume_id : holdArgs.volume,
611 copy_id : holdArgs.copy,
612 hold_type : holdArgs.type,
613 patronid : holdArgs.recipient.id(),
615 pickup_lib : pickuplib
619 /* if we're calling create again (recursing),
620 we know that the hold possibility check already succeeded */
621 holdHandleCreateResponse({_recurse:true, _hold:hold}, true );
624 _debug("hold possible args = "+js2JSON(args));
626 var req = new Request(CHECK_HOLD_POSSIBLE, G.user.session, args );
628 req.request.alertEvent = false;
629 req.request._hold = hold;
630 req.request._recurse = recurse;
631 req.callback(holdHandleCreateResponse);
637 function holdsBuildOrgSelector(node) {
639 if(!node) node = globalOrgTree;
640 if(!isTrue(node.opac_visible())) return;
642 var selector = $('holds_org_selector');
643 var index = selector.options.length;
645 var type = findOrgType(node.ou_type());
646 var indent = type.depth() - 1;
647 var opt = setSelectorVal( selector, index, node.name(), node.id(), null, indent );
648 if(!type.can_have_users()) {
650 addCSSClass(opt, 'disabled_option');
653 for( var i in node.children() ) {
654 var child = node.children()[i];
655 if(child) holdsBuildOrgSelector(child);
659 function holdsBuildHoldFromWindow() {
661 var org = getSelectorVal($('holds_org_selector'));
662 var node = findOrgUnit(org);
663 var ntype = findOrgType(node.ou_type());
664 if(!ntype.can_have_users()) {
665 alertId('holds_pick_good_org');
669 var hold = new ahr();
670 if(holdArgs.editHold) {
671 hold = holdArgs.editHold;
672 holdArgs.editHold = null;
675 if( $('holds_enable_phone').checked ) {
676 var phone = $('holds_phone').value;
677 if( !phone || !phone.match(REGEX_PHONE) ) {
678 alert($('holds_bad_phone').innerHTML);
681 hold.phone_notify(phone);
684 hold.phone_notify("");
687 if( $('holds_enable_email').checked )
688 hold.email_notify(1);
690 hold.email_notify(0);
694 switch(holdArgs.type) {
696 target = holdArgs.metarecord; break;
698 target = holdArgs.record; break;
700 target = holdArgs.volume; break;
702 target = holdArgs.copy; break;
707 hold.pickup_lib(org);
708 //hold.request_lib(org);
709 hold.requestor(holdArgs.requestor.id());
710 hold.usr(holdArgs.recipient.id());
712 hold.hold_type(holdArgs.type);
714 // see if this hold should be frozen and for how long
715 if($('holds_frozen_chkbox').checked) {
717 unHideMe($('hold_frozen_thaw_row'));
718 thawDate = dojo.date.stamp.toISOString(dijit.byId('holds_frozen_thaw_input').getValue());
720 thawDate = holdsVerifyThawDate(thawDate);
722 hold.thaw_date(thawDate);
726 hold.thaw_date(null);
730 hold.thaw_date(null);
733 //check for alternate hold formats
734 var fstring = holdsSetSelectedFormats();
737 hold.holdable_formats(fstring);
738 hold.target(holdArgs.metarecord);
743 function holdsPlaceHold(hold, recurse) {
745 swapCanvas($('check_holds_box'));
746 holdsCheckPossibility(hold.pickup_lib(), hold, recurse);
750 function holdHandleCreateResponse(r, recurse) {
753 var res = r.getResultObject();
754 if(checkILSEvent(res) || res.success != 1) {
755 if(res.success != 1) {
756 alert($('hold_not_allowed').innerHTML);
758 if( res.textcode == 'PATRON_BARRED' ) {
759 alertId('hold_failed_patron_barred');
761 alert($('hold_not_allowed').innerHTML);
764 swapCanvas($('holds_box'));
767 r._hold.selection_depth(res.depth);
770 holdCreateHold(r._recurse, r._hold);
774 function holdCreateHold( recurse, hold ) {
775 var method = CREATE_HOLD;
776 if(recurse) method = CREATE_HOLD_OVERRIDE;
777 var req = new Request( method, holdArgs.requestor.session, hold );
778 req.request.alertEvent = false;
780 var res = req.result();
781 holdProcessResult(hold, res, recurse);
785 runEvt('common', 'holdUpdated');
789 function holdProcessResult( hold, res, recurse ) {
792 alert($('holds_success').innerHTML);
798 alert($('holds_failure').innerHTML);
802 if( grep(res, function(e) { return (e.textcode == 'HOLD_EXISTS'); }) ) {
803 if( fetchPermOrgs('HOLD_EXISTS.override')[0] != -1 ) {
804 if( confirm($('hold_dup_exists_override').innerHTML) ) {
805 return holdsPlaceHold(hold, true);
809 return alert($('hold_dup_exists').innerHTML);
813 alert($('holds_failure').innerHTML);
818 function holdsCancel(holdid, user) {
819 if(!user) user = G.user;
820 var req = new Request(CANCEL_HOLD, user.session, holdid);
823 runEvt('common', 'holdUpdated');
826 function holdsUpdate(hold, user) {
827 if(!user) user = G.user;
828 var req = new Request(UPDATE_HOLD, user.session, hold);
830 var x = req.result(); // cause an exception if there is one
831 runEvt('common', 'holdUpdated');
834 /* verify that the thaw date is valid and after today */
835 function holdsVerifyThawDate(dateString) {
836 thawDate = dojo.date.stamp.fromISOString(dateString);
837 if(thawDate && (dojo.date.compare(thawDate) > 0))
838 return dojo.date.stamp.toISOString(thawDate);
842 function holdsVerifyThawDateUI(element) {
843 value = dojo.date.stamp.toISOString(dijit.byId(element).getValue());
846 removeCSSClass($(element), 'invalid_field');
850 if(!holdsVerifyThawDate(value)) {
851 addCSSClass($(element), 'invalid_field');
853 removeCSSClass($(element), 'invalid_field');