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 var holdTargetTypeMap = {
25 function holdsHandleStaff() {
27 // if we know the recipient's barcode, use it
28 if(xulG.patron_barcode) return _holdsHandleStaff();
30 swapCanvas($('xulholds_box'));
31 $('xul_recipient_barcode').focus();
32 $('xul_recipient_barcode').onkeypress = function(evt)
33 {if(userPressedEnter(evt)) { _holdsHandleStaff(); } };
34 $('xul_recipient_barcode_submit').onclick = _holdsHandleStaff;
35 $('xul_recipient_me').onclick = _holdsHandleStaffMe;
37 $('xul_recipient_barcode').onkeyup = function(evt) {
38 if($('xul_recipient_barcode').value == '')
39 $('xul_recipient_me').disabled = false;
41 $('xul_recipient_me').disabled = true;
45 $('holds_frozen_thaw_input').onchange =
46 function(){holdsVerifyThawDateUI('holds_frozen_thaw_input');}
47 $('holds_frozen_thaw_input').onkeyup =
48 function(){holdsVerifyThawDateUI('holds_frozen_thaw_input');}
50 function _holdsHandleStaffMe() {
51 holdArgs.recipient = G.user;
55 function _holdsHandleStaff() {
56 var barcode = xulG.patron_barcode;
58 barcode = $('xul_recipient_barcode').value;
59 if(xulG.get_barcode) {
60 // We have a "complete the barcode" function, call it (actor = users only)
61 var new_barcode = xulG.get_barcode(window, 'actor', barcode);
62 // If we got a result (boolean false is "no result") check it
64 // user_false string means they picked "None of the above"
65 // Abort before any other events can fire
66 if(new_barcode == "user_false") return;
67 // No error means we have a (hopefully valid) completed barcode to use.
68 // Otherwise, fall through to other methods of checking
69 if(typeof new_barcode.ilsevent == 'undefined')
70 barcode = new_barcode.barcode;
74 var user = grabUserByBarcode( G.user.session, barcode );
77 if(evt = checkILSEvent(user)) {
82 if(!barcode || !user) {
83 alertId('holds_invalid_recipient', barcode);
89 holdArgs.recipient = user;
96 * record, volume, copy (ids)
97 * request, recipient, editHold (objects)
100 function holdsDrawEditor(args) {
102 holdArgs = (args) ? args : holdArgs;
105 noEmailMessage = $('holds_email').removeChild($('holds.no_email'));
107 if(!noEmailMessageXUL)
108 noEmailMessageXUL = $('holds_email').removeChild($('holds.no_email.xul'));
110 if(isXUL() && holdArgs.recipient == null
111 && holdArgs.editHold == null) {
116 if(!holdArgs.recipient) holdArgs.recipient = G.user;
117 if(!holdArgs.requestor) holdArgs.requestor = G.user;
119 if(!(holdArgs.requestor && holdArgs.requestor.session)) {
120 detachAllEvt('common','locationChanged');
121 attachEvt('common','loggedIn', holdsDrawEditor)
126 if(holdArgs.editHold) // flesh the args with the existing hold
127 holdArgsFromHold(holdArgs.editHold, holdArgs);
129 removeCSSClass($('holds_parts_selector'), 'parts-warning');
130 holdArgs.partsSuggestionMade = false;
136 // updates the edit window with the existing hold's data
137 function _holdsUpdateEditHold() {
139 var hold = holdArgs.editHold;
140 var qstats = holdArgs.status;
142 var orgsel = $('holds_org_selector');
143 var frozenbox = $('holds_frozen_chkbox');
145 setSelector(orgsel, hold.pickup_lib());
147 if( hold.capture_time() || qstats.status > 2 ) {
148 frozenbox.disabled = true;
149 $('holds_frozen_thaw_input').disabled = true;
150 if(qstats.status == 3) {
151 // no pickup lib changes while in-transit
152 orgsel.disabled = true;
154 var orgs = fetchPermOrgs('UPDATE_PICKUP_LIB_FROM_HOLDS_SHELF');
156 orgsel.disabled = true;
159 orgsel.disabled = false;
160 frozenbox.disabled = false;
164 $('holds_submit').onclick = holdsEditHold;
165 $('holds_update').onclick = holdsEditHold;
167 if(hold.phone_notify()) {
168 $('holds_enable_phone').checked = true;
169 $('holds_phone').value = hold.phone_notify();
172 $('holds_phone').disabled = true;
173 $('holds_enable_phone').checked = false;
176 if(isTrue(hold.email_notify())) {
177 $('holds_enable_email').checked = true;
180 $('holds_enable_email').checked = false;
183 dijit.byId('holds_expire_time').setValue(dojo.date.stamp.fromISOString(hold.expire_time()));
185 /* populate the hold freezing info */
186 if(!frozenbox.disabled && isTrue(hold.frozen())) {
187 frozenbox.checked = true;
188 unHideMe($('hold_frozen_thaw_row'));
189 if(hold.thaw_date()) {
190 dijit.byId('holds_frozen_thaw_input').setValue(dojo.date.stamp.fromISOString(hold.thaw_date()));
192 dijit.byId('holds_frozen_thaw_input').setValue('');
195 frozenbox.checked = false;
196 dijit.byId('holds_frozen_thaw_input').setValue('');
197 hideMe($('hold_frozen_thaw_row'));
201 function holdsEditHold() {
202 var hold = holdsBuildHoldFromWindow();
206 if(holdArgs.onComplete)
207 holdArgs.onComplete(hold);
210 function holdArgsFromHold(hold, oargs) {
211 var args = (oargs) ? oargs : {};
212 args.type = hold.hold_type();
213 var target = hold.target();
214 args[holdTargetTypeMap[args.type]] = target;
218 function holdFetchObjects(hold, doneCallback) {
220 var args = (hold) ? holdArgsFromHold(hold) : holdArgs;
222 var type = args.type;
226 if( args.copyObject ) {
228 args.copy = args.copyObject.id();
229 args.volume = args.copyObject.call_number();
230 _h_set_vol(args, doneCallback);
233 var creq = new Request(FETCH_COPY, args.copy);
237 var cp = r.getResultObject();
238 args.copyObject = cp;
239 args.volume = args.copyObject.call_number();
240 _h_set_vol(args, doneCallback);
247 _h_set_vol(args, doneCallback);
249 } else if( type == 'I' ) {
250 _h_set_issuance(args, doneCallback);
252 } else if( type == 'P' ) {
253 _h_set_parts(args, doneCallback);
257 _h_set_rec(args, doneCallback);
259 _h_set_rec_descriptors(args, doneCallback);
267 function _h_set_parts(args, doneCallback) {
269 var preq = new Request(
270 'open-ils.fielder:open-ils.fielder.bmp.atomic',
271 {"cache":1, "fields":["label", "record"],"query": {"id":args.part}}
276 var part = r.getResultObject()[0];
277 args.record = part.record;
278 args.partObject = part;
279 _h_set_rec(args, doneCallback);
286 function _h_set_vol(args, doneCallback) {
288 if( args.volumeObject ) {
289 args.volume = args.volumeObject.id();
290 args.record = args.volumeObject.record();
291 _h_set_rec(args, doneCallback);
295 var vreq = new Request(FETCH_VOLUME, args.volume);
298 var vol = r.getResultObject();
299 args.volumeObject = vol;
300 args.record = vol.record();
301 _h_set_rec(args, doneCallback);
308 function _h_set_issuance(args, doneCallback) {
310 if( args.issuanceObject ) {
311 args.issuance = args.issuanceObject.id();
312 args.record = args.issuanceObject.subscription().record_entry();
313 _h_set_rec(args, doneCallback);
317 var vreq = new Request(FETCH_ISSUANCE, [args.issuance]);
320 var issuance = r.getResultObject()[0];
321 args.issuanceObject = issuance;
322 args.record = issuance.subscription().record_entry();
323 _h_set_rec(args, doneCallback);
330 function _h_set_rec(args, doneCallback) {
332 if(args.recordObject)
333 args.record = args.recordObject.doc_id();
335 args.recordObject = findRecord( args.record, 'T' );
337 if( args.type == 'T' || args.type == 'M' ) {
338 _h_set_rec_descriptors(args, doneCallback);
339 //} else if(args.type == 'P') {
340 //_h_get_parts(args, doneCallback);
342 if(doneCallback) doneCallback(args);
347 function _h_set_rec_descriptors(args, doneCallback) {
349 if( ! args.pickup_lib )
350 args.pickup_lib = getSelectorVal($('holds_org_selector'));
352 if(args.pickup_lib === null)
353 args.pickup_lib = args.recipient.home_ou();
355 // grab the list of record desciptors attached to this records metarecord
356 if( ! args.recordDescriptors ) {
357 var params = { pickup_lib: args.pickup_lib };
359 if (args.type == 'M') {
360 if( !args.metarecord && args.record) {
361 params.metarecord = args.metarecord = args.record;
364 params.metarecord = args.metarecordObject.doc_id();
367 params.record = args.record;
370 if( ! args.record ) {
371 if( args.metarecord )
372 params.metarecord = args.metarecord;
374 params.metarecord = args.metarecordObject.doc_id();
377 var req = new Request(FETCH_MR_DESCRIPTORS, params );
380 var data = r.getResultObject();
381 args.recordDescriptors = args.recordDescriptors = data.descriptors;
382 args.metarecord = args.metarecord = data.metarecord;
383 if( args.type == 'M' && ! args.metarecordObject)
384 args.metarecordObject = args.metarecordObject = findRecord(args.metarecord, 'M');
386 _h_get_parts(args, doneCallback);
392 _h_get_parts(args, doneCallback);
398 function _h_get_parts(args, doneCallback) {
400 if(args.type == 'M' || args.editHold || args.holdParts) {
406 var req = new Request(
407 'open-ils.search:open-ils.search.biblio.record_hold_parts',
408 {pickup_lib: args.pickup_lib, record: args.record}
413 args.recordParts = r.getResultObject();
424 function holdsDrawWindow() {
425 swapCanvas($('holds_box'));
426 $('holds_cancel').onclick = function(){ runEvt('common', 'holdUpdateCanceled'), showCanvas() };
427 $('holds_submit').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
428 $('holds_update').onclick = function(){holdsPlaceHold(holdsBuildHoldFromWindow())};
429 holdFetchObjects(null,
433 if(holdArgs.editHold) {
434 hideMe($('holds_submit'));
435 unHideMe($('holds_update'));
436 var req = new Request(FETCH_HOLD_STATUS,
437 G.user.session, holdArgs.editHold.id());
439 holdArgs.status = req.result();
440 _holdsUpdateEditHold();
446 function __holdsDrawWindow() {
448 var rec = holdArgs.recordObject;
449 var vol = holdArgs.volumeObject;
450 var copy = holdArgs.copyObject;
451 var mr = holdArgs.metarecordObject;
453 rec = (rec) ? rec : mr;
455 if(!holdsOrgSelectorBuilt) {
456 holdsBuildOrgSelector(null,0);
457 holdsOrgSelectorBuilt = true;
458 var selector = $('holds_org_selector');
461 var o_loc = findOrgUnit(getOrigLocation());
462 var t = findOrgType(o_loc.ou_type());
463 if( t.can_have_users() )
464 setSelector(selector, o_loc.id());
468 setSelector(selector, holdArgs.recipient.home_ou());
474 var dsel = $('holds_depth_selector');
475 unHideMe($('holds_depth_selector_row'));
476 if(dsel.getElementsByTagName('option').length == 0) {
477 var types = globalOrgTypes;
478 var depth = findOrgDepth(G.user.ws_ou());
481 if(t.depth() > depth) return;
482 insertSelectorVal(dsel, -1, t.opac_label(), t.depth());
489 appendClear($('holds_recipient'), text(
490 holdArgs.recipient.family_name() + ', ' +
491 holdArgs.recipient.first_given_name()));
492 appendClear($('holds_title'), text(rec.title()));
493 appendClear($('holds_author'), text(rec.author()));
495 if( holdArgs.type == 'I' ) {
496 unHideMe($('holds_type_row'));
497 unHideMe($('holds_is_issuance'));
498 unHideMe($('holds_issuance_row'));
499 appendClear($('holds_issuance_label'), text(holdArgs.issuanceObject.label()));
501 } else if( holdArgs.type == 'V' || holdArgs.type == 'C' ) {
503 unHideMe($('holds_type_row'));
504 unHideMe($('holds_cn_row'));
505 appendClear($('holds_cn'), text(holdArgs.volumeObject.label()));
507 if( holdArgs.type == 'V' ) {
508 unHideMe($('holds_is_cn'));
509 hideMe($('holds_is_copy'));
512 hideMe($('holds_is_cn'));
513 unHideMe($('holds_is_copy'));
514 unHideMe($('holds_copy_row'));
515 appendClear($('holds_copy'), text(holdArgs.copyObject.barcode()));
519 hideMe($('holds_type_row'));
520 hideMe($('holds_copy_row'));
521 hideMe($('holds_cn_row'));
522 hideMe($('holds_issuance_row'));
525 if(holdArgs.recordParts && holdArgs.recordParts.length) {
526 var selector = $('holds_parts_selector');
527 unHideMe($('holds_parts_row'));
531 dojo.forEach(selector.options,
532 function(node) { if(node.value != '') nodeList.push(node) } );
534 dojo.forEach(nodeList, function(node) { selector.removeChild(node); });
537 holdArgs.recordParts,
539 insertSelectorVal(selector, -1, part.label, part.id);
543 } else if(holdArgs.type == 'P') {
544 unHideMe($('holds_parts_row'));
545 unHideMe($('holds_parts_label'));
546 appendClear( $('holds_parts_label'), text(holdArgs.partObject.label));
549 removeChildren($('holds_format'));
551 var mods_formats = rec.types_of_resource();
554 if (holdArgs.recordDescriptors && holdArgs.recordDescriptors.length)
555 formats = holdArgs.recordDescriptors[0].item_type();
557 if( holdArgs.type == 'T' ) {
558 var desc = grep( holdArgs.recordDescriptors,
560 return (i.record() == holdArgs.record);
564 formats = desc[0].item_type();
568 if( holdArgs.type == 'M' ) {
570 if(holdArgs.editHold){
571 mr_formats = holdArgs.editHold.holdable_formats();
573 mr_formats = ''; // collect the item_type()s from all holdArgs.recordDescriptors
574 for(var desc in holdArgs.recordDescriptors){
575 if (!holdArgs.recordDescriptors[desc].item_type()) continue;
576 mr_formats += holdArgs.recordDescriptors[desc].item_type();
580 for(var desc in holdArgs.recordDescriptors){
581 if (!holdArgs.recordDescriptors[desc].item_form()) continue;
586 mr_formats += holdArgs.recordDescriptors[desc].item_form();
592 var data = holdsParseMRFormats(mr_formats);
593 mods_formats = data.mods_formats;
594 formats = data.formats;
598 for( var i in mods_formats ) {
599 var res = mods_formats[i];
600 var img = elem("img");
601 setResourcePic(img, res);
602 $('holds_format').appendChild(img);
604 $('holds_format').appendChild(text(' '+ MARCTypeToFriendly(formats[i]) +' '));
606 $('holds_format').appendChild(text(' '+ mods_formats[i] +' '));
607 $('holds_format').appendChild(elem('br'));
611 $('holds_phone').value = holdArgs.recipient.day_phone();
612 appendClear( $('holds_email'), text(holdArgs.recipient.email()));
614 var pref = holdArgs.recipient.prefs[PREF_HOLD_NOTIFY];
617 if( ! pref.match(/email/i) ) {
618 $('holds_enable_email').checked = false;
620 $('holds_enable_email').checked = true;
623 if( ! pref.match(/phone/i) ) {
624 $('holds_phone').disabled = true;
625 $('holds_enable_phone').checked = false;
627 $('holds_phone').disabled = false;
628 $('holds_enable_phone').checked = true;
632 if(!holdArgs.recipient.email()) {
633 $('holds_enable_email').checked = false;
634 $('holds_enable_email').disabled = true;
637 message = noEmailMessageXUL.cloneNode(true);
638 appendClear($('holds_email'), message);
640 message = noEmailMessage.cloneNode(true);
641 appendClear($('holds_email'), message);
642 $('holds.no_email.my_account').setAttribute('href', buildOPACLink({page:MYOPAC},null,true));
647 if(!$('holds_phone').value)
648 $('holds_enable_phone').checked = false;
650 appendClear($('holds_physical_desc'), text(rec.physical_description()));
652 if(holdArgs.type == 'M') hideMe($('hold_physical_desc_row'));
654 holdsSetFormatSelector();
656 $('holds_frozen_chkbox').checked = false;
657 hideMe($('hold_frozen_thaw_row'));
659 var interval = fetchOrgSettingDefault(holdArgs.recipient.home_ou(), 'circ.hold_expire_interval');
662 secs = interval_to_seconds(interval);
663 var expire = new Date();
664 expire.setTime(expire.getTime() + Number(secs + '000'));
665 dijit.byId('holds_expire_time').setValue(expire);
669 function holdsParseMRFormats(str) {
670 var data = str.split(/-/);
673 var mods_formats = [];
675 for( var i = 0; i < data[0].length; i++ ) {
676 formats.push( data[0].charAt(i) );
677 mods_formats.push( MARCFormatToMods( formats[i] ) );
680 formats = uniquify(formats);
681 mods_formats = uniquify(mods_formats);
685 mods_formats : mods_formats,
692 function holdsSetFormatSelector() {
693 var type = holdArgs.type;
694 if( type == 'C' || type == 'V' || type == "I" || holdArgs.editHold ) return;
696 var data = holdsGetFormats();
697 var avail_formats = data.avail_formats;
698 var sel_formats = data.sel_formats;
699 holdArgs.language = data.lang;
701 hideMe($('holds_alt_formats_row_extras'));
702 unHideMe($('holds_alt_formats_row'));
704 unHideMe($('holds_alt_formats_row_extras'));
707 var selector = $('hold_alt_form_selector');
709 for( var i = 0; i < selector.options.length; i++ ) {
710 if (selector.options[i].className.indexOf('hide_me') == -1)
711 hideMe(selector.options[i]);
712 selector.options[i].disabled = true;
715 for( var i = 0; i < avail_formats.length; i++ ) {
716 var form = avail_formats[i];
717 var opt = findFormatSelectorOptByParts(selector,form);
719 if(type=='M') opt.selected=true;
721 opt.disabled = false;
724 // If the user selects a format, P-type holds are no longer an option
725 // disable and reset the P-type form control
726 selector.onchange = function() {
727 var partsSel = $('holds_parts_selector');
728 for(var i = 0; i < selector.options.length; i++) {
729 if(selector.options[i].selected) {
730 partsSel.selectedIndex = 0; // none selected
731 partsSel.disabled = true;
735 partsSel.disabled = false;
739 function findFormatSelectorOptByParts( sel, val ) {
740 var parts = val.split('-');
741 for( var i = 0; i < sel.options.length; i++ ) {
742 var opt = sel.options[i];
743 var oval = opt.value;
744 var oparts = oval.split('-');
745 if( oparts[0].indexOf(parts[0]) > -1 && (!parts[1] || oparts[1].indexOf(parts[1]) > -1) ) return opt;
750 function holdsGetFormats() {
754 var sformats = []; // selected formats
756 var type = holdArgs.type;
757 var desc = holdArgs.recordDescriptors;
758 var rec = holdArgs.record;
759 var mrec = holdArgs.metarecord;
764 for( var i = 0; i < desc.length; i++ ) {
766 if( d.record() == holdArgs.record ) {
767 lang = d.item_lang();
768 holdArgs.myFormat = _t_f_2_format(d.item_type(), d.item_form());
769 sformats.push(holdArgs.myFormat);
774 for( var i = 0; i < desc.length; i++ ) {
776 if( type == 'T' && d.item_lang() != lang ) continue;
777 formats.push( _t_f_2_format(d.item_type(), d.item_form()));
780 } else if( type =='M') {
782 // All available formats are selected by default in MR holds
783 for( var i = 0; i < desc.length; i++ ) {
785 var _tmp_f = _t_f_2_format(d.item_type(), d.item_form());
786 formats.push( _tmp_f );
787 sformats.push( _tmp_f );
791 formats = uniquify(formats);
792 sformats = uniquify(sformats);
796 avail_formats : formats,
797 sel_formats : sformats
803 function _t_f_2_format(type, form) {
804 if( (type == 'a' || type == 't') && form == 's' ) return 'at-s';
805 if( form == 'd' ) return 'at-d';
806 return (type == 'a' || type == 't') ? 'at' : type;
809 function holdsSetSelectedFormats() {
811 var cn = $('holds_alt_formats_row').className;
812 if( cn && cn.match(/hide_me/) ) return;
814 var selector = $('hold_alt_form_selector');
815 var vals = getSelectedList(selector);
817 if(vals.length == 0) return;
821 if( contains(vals, 'at-d') || contains(vals, 'at-s') || contains(vals, 'at')) {
822 if( contains(vals, 'at') ) {
824 } else if (contains(vals, 'at-s') && contains(vals, 'at-d')) {
826 } else if (!contains(vals, 'at-s')) {
833 for( var i = 0; i < vals.length; i++ ) {
835 if( !val.match(/at/) ) fstring = val + fstring;
838 if( holdArgs.language ) {
839 if( fstring.match(/-/) )
840 fstring = fstring + '-' + holdArgs.language;
842 fstring = fstring + '--' + holdArgs.language;
850 function holdsCheckPossibility(pickuplib, hold, recurse) {
853 titleid : holdArgs.record,
854 mrid : holdArgs.metarecord,
855 volume_id : holdArgs.volume,
856 issuanceid : holdArgs.issuance,
857 copy_id : holdArgs.copy,
858 hold_type : holdArgs.type,
859 holdable_formats : holdArgs.holdable_formats,
860 patronid : holdArgs.recipient.id(),
862 pickup_lib : pickuplib,
863 partid : holdArgs.part
867 /* if we're calling create again (recursing),
868 we know that the hold possibility check already succeeded */
869 holdHandleCreateResponse({_recurse:true, _hold:hold}, true );
872 _debug("hold possible args = "+js2JSON(args));
874 var req = new Request(CHECK_HOLD_POSSIBLE, G.user.session, args );
876 req.request.alertEvent = false;
877 req.request._hold = hold;
878 req.request._recurse = recurse;
879 req.callback(holdHandleCreateResponse);
885 function holdsBuildOrgSelector(node) {
887 if(!node) node = globalOrgTree;
888 if(!isTrue(node.opac_visible()) && !isXUL()) return;
890 var render_this_org = true;
891 var orgHiding = checkOrgHiding(); // value here is cached so not too painful with the recursion
893 if (node.id() == globalOrgTree.id()) {
894 node = orgHiding.org; // top of tree = org hiding context org
896 if ( ! orgIsMine( orgHiding.org, node, orgHiding.depth ) ) {
897 render_this_org = false;
901 if (render_this_org) {
902 var selector = $('holds_org_selector');
903 var index = selector.options.length;
905 var type = findOrgType(node.ou_type());
906 var indent = type.depth() - 1;
908 var opt = setSelectorVal( selector, index, node.name(), node.id(), null, indent );
909 if(!type.can_have_users()) {
911 addCSSClass(opt, 'disabled_option');
915 for( var i in node.children() ) {
916 var child = node.children()[i];
917 if(child) holdsBuildOrgSelector(child);
921 function holdsBuildHoldFromWindow() {
923 var org = getSelectorVal($('holds_org_selector'));
924 var node = findOrgUnit(org);
925 var ntype = findOrgType(node.ou_type());
926 if(!ntype.can_have_users()) {
927 alertId('holds_pick_good_org');
931 fieldmapper.IDL.load(['ahr']);
932 var hold = new ahr();
933 if(holdArgs.editHold) {
934 hold = holdArgs.editHold;
935 holdArgs.editHold = null;
938 if( $('holds_enable_phone').checked ) {
939 var phone = $('holds_phone').value;
940 if( !phone || !phone.match(REGEX_PHONE) ) {
941 alert($('holds_bad_phone').innerHTML);
944 hold.phone_notify(phone);
947 hold.phone_notify("");
950 if( $('holds_enable_email').checked )
951 hold.email_notify(1);
953 hold.email_notify(0);
955 var part = getSelectorVal($('holds_parts_selector'));
958 holdArgs.part = part;
961 var target = holdArgs[holdTargetTypeMap[holdArgs.type]];
963 // a mono part is selected
965 hold.pickup_lib(org);
966 //hold.request_lib(org);
967 hold.requestor(holdArgs.requestor.id());
968 hold.usr(holdArgs.recipient.id());
970 hold.hold_type(holdArgs.type);
972 var expDate = dijit.byId('holds_expire_time').getValue();
974 var expireDate = dojo.date.stamp.toISOString(expDate);
975 expireDate = holdsVerifyThawDate(expireDate);
977 hold.expire_time(expireDate);
982 // see if this hold should be frozen and for how long
983 if($('holds_frozen_chkbox').checked) {
985 unHideMe($('hold_frozen_thaw_row'));
986 var thawDate = dijit.byId('holds_frozen_thaw_input').attr('value');
988 thawDate = dojo.date.stamp.toISOString(thawDate);
989 thawDate = holdsVerifyThawDate(thawDate);
991 hold.thaw_date(thawDate);
995 hold.thaw_date(null);
999 hold.thaw_date(null);
1002 //check for alternate hold formats
1003 var fstring = holdsSetSelectedFormats();
1005 hold.hold_type('M');
1006 hold.holdable_formats(fstring);
1008 holdArgs.holdable_formats = fstring;
1009 hold.target(holdArgs.metarecord);
1014 function holdsPlaceHold(hold, recurse) {
1016 swapCanvas($('check_holds_box'));
1017 holdsCheckPossibility(hold.pickup_lib(), hold, recurse);
1021 function holdHandleCreateResponse(r, recurse) {
1024 var res = r.getResultObject();
1025 var place_anyway = false;
1026 if(checkILSEvent(res) || res.success != 1) {
1027 if(res.success != 1) {
1028 if(res.age_protected_copy == 1) {
1029 // There is at least one copy that *could* fill the hold, if it were not age-protected.
1030 if( confirm($('hold_age_protected_override').innerHTML) ) {
1031 place_anyway = true;
1033 swapCanvas($('holds_box'));
1036 } else if(res.place_unfillable == 1) {
1037 if( confirm($('hold_place_unfillable_override').innerHTML) ) {
1038 place_anyway = true;
1040 swapCanvas($('holds_box'));
1046 if(res.success != 1) {
1048 if(!holdArgs.partsSuggestionMade && holdArgs.recordParts &&
1049 holdArgs.recordParts.length && holdArgs.type == 'T') {
1050 // T holds on records that have parts are OK, but if the record has no non-part
1051 // copies, the hold will ultimately fail. Suggest selecting a part to the user.
1052 addCSSClass($('holds_parts_selector'), 'parts-warning');
1053 holdArgs.partsSuggestionMade = true;
1054 alert($('hold_has_parts').innerHTML);
1056 alert($('hold_not_allowed').innerHTML);
1059 if( res.textcode == 'PATRON_BARRED' ) {
1060 alertId('hold_failed_patron_barred');
1062 alert($('hold_not_allowed').innerHTML);
1065 swapCanvas($('holds_box'));
1069 r._hold.selection_depth(res.depth);
1072 holdCreateHold(r._recurse, r._hold);
1076 function holdCreateHold( recurse, hold ) {
1077 var method = CREATE_HOLD;
1078 if(recurse) method = CREATE_HOLD_OVERRIDE;
1079 var req = new Request( method, holdArgs.requestor.session, hold );
1080 req.request.alertEvent = false;
1082 var res = req.result();
1083 holdProcessResult(hold, res, recurse);
1087 runEvt('common', 'holdUpdated');
1091 function holdProcessResult( hold, res, recurse ) {
1093 if( res && res > -1 ) {
1094 alert($('holds_success').innerHTML);
1096 if(isXUL() && typeof xulG.opac_hold_placed == 'function')
1097 xulG.opac_hold_placed(res);
1102 alert($('holds_failure').innerHTML);
1106 if( grep(res, function(e) { return (e.textcode == 'HOLD_EXISTS'); }) ) {
1107 if( fetchPermOrgs('HOLD_EXISTS.override')[0] != -1 ) {
1108 if( confirm($('hold_dup_exists_override').innerHTML) ) {
1109 return holdsPlaceHold(hold, true);
1114 return alert($('hold_dup_exists').innerHTML);
1118 if( grep(res, function(e) { return (e.textcode == 'HOLD_ITEM_CHECKED_OUT'); }) ) {
1119 if( fetchPermOrgs('HOLD_ITEM_CHECKED_OUT.override')[0] != -1 ) {
1120 if( confirm($('hold_checked_out_override').innerHTML) ) {
1121 return holdsPlaceHold(hold, true);
1126 return alert($('hold_checked_out').innerHTML);
1131 alert($('holds_failure').innerHTML);
1136 function holdsCancel(holdid, user) {
1137 if(!user) user = G.user;
1138 var req = new Request(CANCEL_HOLD, user.session, holdid, /* Patron via OPAC */ 6);
1140 return req.result();
1141 runEvt('common', 'holdUpdated');
1144 function holdsUpdate(hold, user) {
1145 if(!user) user = G.user;
1146 var req = new Request(UPDATE_HOLD, user.session, hold);
1148 var x = req.result(); // cause an exception if there is one
1149 runEvt('common', 'holdUpdated');
1152 /* verify that the thaw date is valid and after today */
1153 function holdsVerifyThawDate(dateString, isGreater) {
1154 thawDate = dojo.date.stamp.fromISOString(dateString);
1157 if(dojo.date.compare(thawDate) > 0) {
1158 return dojo.date.stamp.toISOString(thawDate);
1161 return dojo.date.stamp.toISOString(thawDate);
1167 function holdsVerifyThawDateUI(element) {
1168 value = dojo.date.stamp.toISOString(dijit.byId(element).getValue());
1171 removeCSSClass($(element), 'invalid_field');
1175 if(!holdsVerifyThawDate(value, true)) {
1176 addCSSClass($(element), 'invalid_field');
1178 removeCSSClass($(element), 'invalid_field');