From 326d7670896babaf7fa0067d1f79f4dcec9a70b2 Mon Sep 17 00:00:00 2001 From: phasefx Date: Fri, 18 Sep 2009 20:29:15 +0000 Subject: [PATCH] Renew Item interface, where you can scan in the item barcodes and a renewal attempt is made automatically. Not as clean as it could be if implemented from scratch; it's a paired down derivative of the checkin interface. Possible TODO: Provide an Override checkbox so that all subsequent renewal attempts are made with .override git-svn-id: svn://svn.open-ils.org/ILS/trunk@14060 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/web/opac/locale/en-US/lang.dtd | 37 ++ .../chrome/content/main/constants.js | 1 + .../staff_client/chrome/content/main/menu.js | 7 + .../chrome/content/main/menu_frame_menus.xul | 3 + .../xul/staff_client/server/circ/renew.js | 378 ++++++++++++++++++ .../xul/staff_client/server/circ/renew.xul | 97 +++++ .../server/circ/renew_overlay.xul | 123 ++++++ .../server/locale/en-US/circ.properties | 2 +- 8 files changed, 647 insertions(+), 1 deletion(-) create mode 100644 Open-ILS/xul/staff_client/server/circ/renew.js create mode 100644 Open-ILS/xul/staff_client/server/circ/renew.xul create mode 100644 Open-ILS/xul/staff_client/server/circ/renew_overlay.xul diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd index a8c28aa202..d05473735e 100644 --- a/Open-ILS/web/opac/locale/en-US/lang.dtd +++ b/Open-ILS/web/opac/locale/en-US/lang.dtd @@ -350,6 +350,8 @@ + + @@ -418,6 +420,13 @@ + + + + + + + @@ -744,6 +753,8 @@ + + @@ -1775,6 +1786,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Open-ILS/xul/staff_client/chrome/content/main/constants.js b/Open-ILS/xul/staff_client/chrome/content/main/constants.js index 6043e55f16..56b672b4d4 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/constants.js +++ b/Open-ILS/xul/staff_client/chrome/content/main/constants.js @@ -275,6 +275,7 @@ const urls = { 'XUL_BIB_BRIEF' : '/xul/server/cat/bib_brief.xul', 'XUL_BROWSER' : 'chrome://open_ils_staff_client/content/util/browser.xul', 'XUL_CHECKIN' : '/xul/server/circ/checkin.xul', + 'XUL_RENEW' : '/xul/server/circ/renew.xul', 'XUL_CHECKOUT' : '/xul/server/circ/checkout.xul', 'XUL_CIRC_BRIEF' : '/xul/server/circ/circ_brief.xul', 'XUL_CIRC_SUMMARY' : '/xul/server/circ/circ_summary.xul', diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu.js b/Open-ILS/xul/staff_client/chrome/content/main/menu.js index c8e3293dc0..297c64ae62 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/menu.js +++ b/Open-ILS/xul/staff_client/chrome/content/main/menu.js @@ -394,6 +394,13 @@ main.menu.prototype = { obj.set_tab(obj.url_prefix(urls.XUL_CHECKIN),{},{}); } ], + 'cmd_circ_renew' : [ + ['oncommand'], + function() { + obj.data.stash_retrieve(); + obj.set_tab(obj.url_prefix(urls.XUL_RENEW),{},{}); + } + ], 'cmd_circ_checkout' : [ ['oncommand'], function() { diff --git a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul index 0599c16499..5de0c1027a 100644 --- a/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul +++ b/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul @@ -25,6 +25,7 @@ + @@ -132,6 +133,7 @@ + @@ -179,6 +181,7 @@ + diff --git a/Open-ILS/xul/staff_client/server/circ/renew.js b/Open-ILS/xul/staff_client/server/circ/renew.js new file mode 100644 index 0000000000..54a07fd6fe --- /dev/null +++ b/Open-ILS/xul/staff_client/server/circ/renew.js @@ -0,0 +1,378 @@ +dump('entering circ.renew.js\n'); + +if (typeof circ == 'undefined') circ = {}; +circ.renew = function (params) { + + JSAN.use('util.error'); this.error = new util.error(); + JSAN.use('util.network'); this.network = new util.network(); + JSAN.use('util.barcode'); + JSAN.use('util.date'); + this.OpenILS = {}; JSAN.use('OpenILS.data'); this.OpenILS.data = new OpenILS.data(); this.OpenILS.data.init({'via':'stash'}); + this.data = this.OpenILS.data; +} + +circ.renew.prototype = { + + 'selection_list' : [], + + 'init' : function( params ) { + + var obj = this; + + JSAN.use('circ.util'); + var columns = circ.util.columns( + { + 'barcode' : { 'hidden' : false }, + 'title' : { 'hidden' : false }, + 'location' : { 'hidden' : false }, + 'call_number' : { 'hidden' : false }, + 'status' : { 'hidden' : false }, + 'alert_message' : { 'hidden' : false }, + 'due_date' : { 'hidden' : false }, + 'due_time' : { 'hidden' : false } + }, + { + 'except_these' : [ 'uses', 'checkin_time_full' ] + } + ); + + JSAN.use('util.list'); obj.list = new util.list('renew_list'); + obj.list.init( + { + 'columns' : columns, + 'map_row_to_columns' : circ.util.std_map_row_to_columns(), + 'on_select' : function(ev) { + try { + JSAN.use('util.functional'); + var sel = obj.list.retrieve_selection(); + obj.selection_list = util.functional.map_list( + sel, + function(o) { return JSON2js(o.getAttribute('retrieve_id')); } + ); + obj.error.sdump('D_TRACE', 'circ/copy_status: selection list = ' + js2JSON(obj.selection_list) ); + if (obj.selection_list.length == 0) { + obj.controller.view.sel_edit.setAttribute('disabled','true'); + obj.controller.view.sel_opac.setAttribute('disabled','true'); + obj.controller.view.sel_patron.setAttribute('disabled','true'); + obj.controller.view.sel_last_patron.setAttribute('disabled','true'); + obj.controller.view.sel_copy_details.setAttribute('disabled','true'); + obj.controller.view.sel_bucket.setAttribute('disabled','true'); + obj.controller.view.sel_spine.setAttribute('disabled','true'); + obj.controller.view.sel_transit_abort.setAttribute('disabled','true'); + obj.controller.view.sel_clip.setAttribute('disabled','true'); + obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','true'); + } else { + obj.controller.view.sel_edit.setAttribute('disabled','false'); + obj.controller.view.sel_opac.setAttribute('disabled','false'); + obj.controller.view.sel_patron.setAttribute('disabled','false'); + obj.controller.view.sel_last_patron.setAttribute('disabled','false'); + obj.controller.view.sel_copy_details.setAttribute('disabled','false'); + obj.controller.view.sel_bucket.setAttribute('disabled','false'); + obj.controller.view.sel_spine.setAttribute('disabled','false'); + obj.controller.view.sel_transit_abort.setAttribute('disabled','false'); + obj.controller.view.sel_clip.setAttribute('disabled','false'); + obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','false'); + } + } catch(E) { + alert('FIXME: ' + E); + } + } + } + ); + + JSAN.use('util.controller'); obj.controller = new util.controller(); + obj.controller.init( + { + 'control_map' : { + 'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ], + 'sel_clip' : [ + ['command'], + function() { + obj.list.clipboard(); + obj.controller.view.renew_barcode_entry_textbox.focus(); + } + ], + 'sel_edit' : [ + ['command'], + function() { + try { + obj.spawn_copy_editor(); + } catch(E) { + alert(E); + } + } + ], + 'sel_spine' : [ + ['command'], + function() { + JSAN.use('cat.util'); + cat.util.spawn_spine_editor(obj.selection_list); + } + ], + 'sel_opac' : [ + ['command'], + function() { + JSAN.use('cat.util'); + cat.util.show_in_opac(obj.selection_list); + } + ], + 'sel_transit_abort' : [ + ['command'], + function() { + JSAN.use('circ.util'); + circ.util.abort_transits(obj.selection_list); + } + ], + 'sel_patron' : [ + ['command'], + function() { + JSAN.use('circ.util'); + circ.util.show_last_few_circs(obj.selection_list); + } + ], + 'sel_last_patron' : [ + ['command'], + function() { + var patrons = {}; + for (var i = 0; i < obj.selection_list.length; i++) { + var circs = obj.network.simple_request('FM_CIRC_RETRIEVE_VIA_COPY',[ses(),obj.selection_list[i].copy_id,1]); + if (circs.length > 0) { + patrons[circs[0].usr()] = 1; + } else { + alert(document.getElementById('circStrings').getFormattedString('staff.circ.item_no_circs', [obj.selection_list[i].barcode])); + } + } + for (var i in patrons) { + xulG.new_patron_tab({},{'id' : i}); + } + } + ], + 'sel_copy_details' : [ + ['command'], + function() { + JSAN.use('circ.util'); + for (var i = 0; i < obj.selection_list.length; i++) { + circ.util.show_copy_details( obj.selection_list[i].copy_id ); + } + } + ], + 'sel_mark_items_damaged' : [ + ['command'], + function() { + var funcs = []; + JSAN.use('cat.util'); JSAN.use('util.functional'); + cat.util.mark_item_damaged( util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } ) ); + } + ], + 'sel_bucket' : [ + ['command'], + function() { + JSAN.use('cat.util'); + cat.util.add_copies_to_bucket(obj.selection_list); + } + ], + 'renew_barcode_entry_textbox' : [ + ['keypress'], + function(ev) { + if (ev.keyCode && ev.keyCode == 13) { + obj.renew(); + } + } + ], + 'cmd_broken' : [ + ['command'], + function() { alert(document.getElementById('circStrings').getString('staff.circ.unimplemented')); } + ], + 'cmd_renew_submit_barcode' : [ + ['command'], + function() { + obj.renew(); + } + ], + 'cmd_renew_print' : [ + ['command'], + function() { + var p = { + 'template' : 'renew' + }; + obj.list.print(p); + } + ], + 'cmd_csv_to_clipboard' : [ ['command'], function() { + obj.list.dump_csv_to_clipboard(); + obj.controller.view.renew_barcode_entry_textbox.focus(); + } ], + 'cmd_csv_to_printer' : [ ['command'], function() { + obj.list.dump_csv_to_printer(); + obj.controller.view.renew_barcode_entry_textbox.focus(); + } ], + 'cmd_csv_to_file' : [ ['command'], function() { + obj.list.dump_csv_to_file( { 'defaultFileName' : 'checked_in.txt' } ); + obj.controller.view.renew_barcode_entry_textbox.focus(); + } ] + } + } + ); + this.controller.render(); + this.controller.view.renew_barcode_entry_textbox.focus(); + + }, + + 'test_barcode' : function(bc) { + var obj = this; + var x = document.getElementById('strict_barcode'); + if (x && x.checked != true) return true; + var good = util.barcode.check(bc); + if (good) { + return true; + } else { + if ( 1 == obj.error.yns_alert( + document.getElementById('circStrings').getFormattedString('staff.circ.check_digit.bad', [bc]), + document.getElementById('circStrings').getString('staff.circ.barcode.bad'), + document.getElementById('circStrings').getString('staff.circ.cancel'), + document.getElementById('circStrings').getString('staff.circ.barcode.accept'), + null, + document.getElementById('circStrings').getString('staff.circ.confirm'), + '/xul/server/skin/media/images/bad_barcode.png' + ) ) { + return true; + } else { + return false; + } + } + }, + + 'renew' : function() { + var obj = this; + try { + var barcode = obj.controller.view.renew_barcode_entry_textbox.value; + if (!barcode) return; + if (barcode) { + if ( obj.test_barcode(barcode) ) { /* good */ } else { /* bad */ return; } + } + var auto_print = document.getElementById('renew_auto'); + if (auto_print) auto_print = auto_print.checked; + JSAN.use('circ.util'); + var renew = circ.util.renew_via_barcode( + barcode, + null, + function( r ) { + obj.renew_followup( r, barcode ); + } + ); + } catch(E) { + obj.error.standard_unexpected_error_alert('Error in circ/renew.js, renew():', E); + if (typeof obj.on_failure == 'function') { + obj.on_failure(E); + } + if (typeof window.xulG == 'object' && typeof window.xulG.on_failure == 'function') { + window.xulG.on_failure(E); + } + } + }, + + 'renew_followup' : function(r,bc) { + var obj = this; + try { + if (!r) return obj.on_failure(); /* circ.util.renew handles errors and returns null currently */ + if ( (typeof r[0].ilsevent != 'undefined' && r[0].ilsevent == 0) ) { + // SUCCESS + var x = document.getElementById('no_change_label'); + if (x) { + x.hidden = true; + x.setAttribute('value',''); + } + } else { + // FAILURE + var msg = document.getElementById("patronStrings").getFormattedString('staff.patron.items.items_renew.not_renewed',[bc, r[0].textcode + r[0].desc]); + var x = document.getElementById('no_change_label'); + if (x) { + x.hidden = false; + x.setAttribute('value',msg); + } + obj.controller.view.renew_barcode_entry_textbox.focus(); + obj.controller.view.renew_barcode_entry_textbox.select(); + return; + } + var renew = r[0].payload; + var retrieve_id = js2JSON( { 'copy_id' : renew.copy.id(), 'barcode' : renew.copy.barcode(), 'doc_id' : (renew.record == null ? null : renew.record.doc_id() ) } ); + if (document.getElementById('trim_list')) { + var x = document.getElementById('trim_list'); + if (x.checked) { obj.list.trim_list = 20; } else { obj.list.trim_list = null; } + } + obj.list.append( + { + 'retrieve_id' : retrieve_id, + 'row' : { + 'my' : { + 'circ' : renew.circ, + 'mvr' : renew.record, + 'acp' : renew.copy, + 'status' : renew.status, + 'route_to' : renew.route_to, + 'message' : renew.message + } + }, + 'to_top' : true + } + ); + obj.list.node.view.selection.select(0); + + JSAN.use('util.sound'); var sound = new util.sound(); sound.circ_good(); + + if (typeof obj.on_renew == 'function') { + obj.on_renew(renew); + } + if (typeof window.xulG == 'object' && typeof window.xulG.on_renew == 'function') { + window.xulG.on_renew(renew); + } + + return true; + + } catch(E) { + obj.error.standard_unexpected_error_alert('Error in circ/renew.js, renew_followup():', E); + if (typeof obj.on_failure == 'function') { + obj.on_failure(E); + } + if (typeof window.xulG == 'object' && typeof window.xulG.on_failure == 'function') { + window.xulG.on_failure(E); + } + } + + }, + + 'on_renew' : function() { + this.controller.view.renew_barcode_entry_textbox.disabled = false; + this.controller.view.renew_barcode_entry_textbox.select(); + this.controller.view.renew_barcode_entry_textbox.value = ''; + this.controller.view.renew_barcode_entry_textbox.focus(); + }, + + 'on_failure' : function() { + this.controller.view.renew_barcode_entry_textbox.disabled = false; + this.controller.view.renew_barcode_entry_textbox.select(); + this.controller.view.renew_barcode_entry_textbox.focus(); + }, + + 'spawn_copy_editor' : function() { + + var obj = this; + + JSAN.use('util.functional'); + + var list = obj.selection_list; + + list = util.functional.map_list( + list, + function (o) { + return o.copy_id; + } + ); + + JSAN.use('cat.util'); cat.util.spawn_copy_editor( { 'copy_ids' : list, 'edit' : 1 } ); + + } + +} + +dump('exiting circ.renew.js\n'); diff --git a/Open-ILS/xul/staff_client/server/circ/renew.xul b/Open-ILS/xul/staff_client/server/circ/renew.xul new file mode 100644 index 0000000000..15c10ae98a --- /dev/null +++ b/Open-ILS/xul/staff_client/server/circ/renew.xul @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Open-ILS/xul/staff_client/server/circ/renew_overlay.xul b/Open-ILS/xul/staff_client/server/circ/renew_overlay.xul new file mode 100644 index 0000000000..65ca8db471 --- /dev/null +++ b/Open-ILS/xul/staff_client/server/circ/renew_overlay.xul @@ -0,0 +1,123 @@ + + + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +