[open-ils-commits] r15247 - in trunk/Open-ILS: src/perlmods/OpenILS/Application web/css/skin/default web/js/dojo/openils/booking/nls web/js/ui/default/booking web/opac/locale/en-US web/templates/default/booking xul/staff_client/chrome/content/main xul/staff_client/chrome/locale/en-US xul/staff_client/server/patron (miker)
svn at svn.open-ils.org
svn at svn.open-ils.org
Wed Dec 30 10:43:35 EST 2009
Author: miker
Date: 2009-12-30 10:43:32 -0500 (Wed, 30 Dec 2009)
New Revision: 15247
Added:
trunk/Open-ILS/web/js/dojo/openils/booking/nls/pull_list.js
trunk/Open-ILS/web/js/ui/default/booking/common.js
trunk/Open-ILS/web/js/ui/default/booking/pull_list.js
trunk/Open-ILS/web/templates/default/booking/pull_list.tt2
Modified:
trunk/Open-ILS/src/perlmods/OpenILS/Application/Booking.pm
trunk/Open-ILS/web/css/skin/default/booking.css
trunk/Open-ILS/web/js/dojo/openils/booking/nls/reservation.js
trunk/Open-ILS/web/js/ui/default/booking/reservation.js
trunk/Open-ILS/web/opac/locale/en-US/lang.dtd
trunk/Open-ILS/web/templates/default/booking/reservation.tt2
trunk/Open-ILS/xul/staff_client/chrome/content/main/menu.js
trunk/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul
trunk/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties
trunk/Open-ILS/xul/staff_client/server/patron/display_horiz_overlay.xul
trunk/Open-ILS/xul/staff_client/server/patron/display_overlay.xul
Log:
Patch from Lebbeous Fogle-Weekley adding a pull list interface for booking reservations
Modified: trunk/Open-ILS/src/perlmods/OpenILS/Application/Booking.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/Booking.pm 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/Booking.pm 2009-12-30 15:43:32 UTC (rev 15247)
@@ -3,6 +3,7 @@
use strict;
use warnings;
+use POSIX qw/strftime/;
use OpenILS::Application;
use base qw/OpenILS::Application/;
@@ -478,7 +479,10 @@
} ];
$cstore->disconnect;
- return $ids if not $whole_obj;
+ if (not $whole_obj) {
+ $e->disconnect;
+ return $ids;
+ }
my $bresv_list = $e->search_booking_reservation([
{"id" => $ids},
@@ -489,6 +493,7 @@
}
}]
);
+ $e->disconnect;
return $bresv_list ? $bresv_list : [];
}
__PACKAGE__->register_method(
@@ -522,27 +527,48 @@
);
+sub naive_ts_string { strftime("%F %T", localtime(shift)); }
+
sub get_pull_list {
- my ($self, $client, $auth, $range, $pickup_lib) = @_;
+ my ($self, $client, $auth, $range, $interval_secs, $pickup_lib) = @_;
my $e = new_editor(xact => 1, authtoken => $auth);
return $e->die_event unless $e->checkauth;
return $e->die_event unless $e->allowed('RETRIEVE_RESERVATION_PULL_LIST');
- return $e->die_event unless ref($range) eq 'ARRAY';
+ return $e->die_event unless (
+ ref($range) eq 'ARRAY' or
+ ($interval_secs = int($interval_secs)) > 0
+ );
+ $range = [ naive_ts_string(time), naive_ts_string(time + $interval_secs) ]
+ if not $range;
+
+ my @fundamental_constraints = (
+ {"current_resource" => {"!=" => undef}},
+ {"capture_time" => undef},
+ {"cancel_time" => undef},
+ {"return_time" => undef},
+ {"pickup_time" => undef}
+ );
+
my $query = {
- "select" => {"bresv" => ["id"]},
+ "select" => {
+ "bresv" => [
+ "current_resource",
+ {
+ "column" => "start_time",
+ "transform" => "min",
+ "aggregate" => 1
+ }
+ ]
+ },
"from" => "bresv",
"where" => {
"-and" => [
json_query_ranges_overlap(
$range->[0], $range->[1], "start_time", "end_time"
),
- {"current_resource" => {"!=" => undef}},
- {"capture_time" => undef},
- {"cancel_time" => undef},
- {"return_time" => undef},
- {"pickup_time" => undef}
+ @fundamental_constraints
],
}
};
@@ -550,33 +576,128 @@
push @{$query->{"where"}->{"-and"}}, {"pickup_lib" => $pickup_lib};
}
- my $ids = [ map { $_->{id} } @{$e->json_query($query)} ];
- if (@$ids) {
- my $bresv_list = $e->search_booking_reservation([
- {"id" => $ids}, {
- flesh => 1,
- flesh_fields => {
- bresv => [qw/usr target_resource_type current_resource/]
- }
+ my $rows = $e->json_query($query);
+ my %resource_id_map = ();
+ my @all_ids = ();
+ if (@$rows) {
+ my $id_query = {
+ "select" => {"bresv" => ["id"]},
+ "from" => "bresv",
+ "where" => {
+ "-and" => [
+ {"current_resource" => "PLACEHOLDER"},
+ {"start_time" => "PLACEHOLDER"},
+ ]
}
- ]);
- return $bresv_list ? $bresv_list : [];
+ };
+ if ($pickup_lib) {
+ push @{$id_query->{"where"}->{"-and"}},
+ {"pickup_lib" => $pickup_lib};
+ }
+
+ foreach (@$rows) {
+ $id_query->{"where"}->{"-and"}->[0]->{"current_resource"} =
+ $_->{"current_resource"};
+ $id_query->{"where"}->{"-and"}->[1]->{"start_time"} =
+ $_->{"start_time"};
+
+ my $results = $e->json_query($id_query);
+ if (@$results) {
+ my @these_ids = map { $_->{"id"} } @$results;
+ push @all_ids, @these_ids;
+
+ $resource_id_map{$_->{"current_resource"}} = [@these_ids];
+ }
+ }
+ }
+ if (@all_ids) {
+ my %bresv_lookup = (
+ map { $_->id => $_ } @{
+ $e->search_booking_reservation([{"id" => [@all_ids]}, {
+ flesh => 1,
+ flesh_fields => { bresv => [
+ "usr",
+ "target_resource_type",
+ "current_resource"
+ ]}
+ }])
+ }
+ );
+ $e->disconnect;
+ return [ map {
+ my $key = $_;
+ my $one = $bresv_lookup{$resource_id_map{$key}->[0]};
+ my $result = {
+ "current_resource" => $one->current_resource,
+ "target_resource_type" => $one->target_resource_type,
+ "reservations" => [
+ map { $bresv_lookup{$_} } @{$resource_id_map{$key}}
+ ]
+ };
+ foreach (@{$result->{"reservations"}}) { # deflesh
+ $_->current_resource($_->current_resource->id);
+ $_->target_resource_type($_->target_resource_type->id);
+ }
+ $result;
+ } keys %resource_id_map ];
} else {
- return $ids; # empty list
+ $e->disconnect;
+ return [];
}
}
__PACKAGE__->register_method(
method => "get_pull_list",
api_name => "open-ils.booking.reservations.get_pull_list",
+ argc => 4,
+ signature=> {
+ params => [
+ {type => "string", desc => "Authentication token"},
+ {type => "array", desc =>
+ "range: Date/time range for reservations (opt)"},
+ {type => "int", desc =>
+ "interval: Seconds from now (instead of range)"},
+ {type => "number", desc => "(Optional) Pickup library"}
+ ],
+ return => { desc => "An array of hashes, each containing key/value " .
+ "pairs describing resource, resource type, and a list of " .
+ "reservations that claim the given resource." }
+ }
+);
+
+
+sub get_copy_fleshed_just_right {
+ my ($self, $client, $auth, $barcode) = @_;
+
+ my $e = new_editor(authtoken => $auth);
+ my $results = $e->search_asset_copy([
+ {"barcode" => $barcode},
+ {
+ "flesh" => 1,
+ "flesh_fields" => {"acp" => [qw/call_number location/]}
+ }
+ ]);
+
+ if (ref($results) eq 'ARRAY') {
+ $e->disconnect;
+ return $results->[0] unless ref $barcode;
+ return +{ map { $_->barcode => $_ } @$results };
+ } else {
+ return $e->die_event;
+ }
+}
+__PACKAGE__->register_method(
+ method => "get_copy_fleshed_just_right",
+ api_name => "open-ils.booking.asset.get_copy_fleshed_just_right",
argc => 2,
signature=> {
params => [
- {type => 'string', desc => 'Authentication token'},
- {type => 'array', desc => 'Date/time range for reservations'},
- {type => 'number', desc => '(Optional) Pickup library'}
+ {type => "string", desc => "Authentication token"},
+ {type => "mixed", desc => "One barcode or an array of them"},
],
- return => { desc => "An array of reservations, fleshed with usr, " .
- "current_resource, and target_resource_type" }
+ return => { desc =>
+ "A copy, or a hash of copies keyed by barcode if an array of " .
+ "barcodes was given"
+ }
}
);
Modified: trunk/Open-ILS/web/css/skin/default/booking.css
===================================================================
--- trunk/Open-ILS/web/css/skin/default/booking.css 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/web/css/skin/default/booking.css 2009-12-30 15:43:32 UTC (rev 15247)
@@ -52,6 +52,23 @@
font-weight: bold;
font-style: italic;
}
-div#preselected_patron {
- font-size: 12pt;
+input#arbitrary_resource { margin-left: 8px; margin-right: 8px; }
+div#or { font-size: 12pt; font-weight: bold; }
+input#interval_in_days { width: 75px; }
+table#the_table thead tr th {
+ vertical-align: top;
+ background-color: #dddddd;
+ color: #000000;
+ font-weight: bold;
+ padding: 0 6px 0 6px;
+ border-left: 1px #333333 solid;
+ border-right: 1px #333333 solid;
}
+tbody#the_table_body td {
+ vertical-align: top;
+ padding: 2px;
+ border-top: 1px #cccccc solid;
+ border-left: 1px #cccccc solid;
+ border-bottom: 1px #333333 solid;
+ border-right: 1px #333333 solid;
+}
Added: trunk/Open-ILS/web/js/dojo/openils/booking/nls/pull_list.js
===================================================================
--- trunk/Open-ILS/web/js/dojo/openils/booking/nls/pull_list.js (rev 0)
+++ trunk/Open-ILS/web/js/dojo/openils/booking/nls/pull_list.js 2009-12-30 15:43:32 UTC (rev 15247)
@@ -0,0 +1,19 @@
+{
+ 'PULL_LIST_NO_RESPONSE': "No response from server trying to get pull list!",
+ 'PULL_LIST_ERROR': "Error trying to fetch pull list: ",
+ 'COPY_LOOKUP_NO_RESPONSE': "No response looking up copies by barcode",
+ 'COPY_LOOKUP_ERROR': "Error looking up copies by barcode: ",
+ 'COPY_MISSING': "Unexpected error: No information for copy: ",
+
+ 'AUTO_pickup_lib_selector': "Select a location for pickup:",
+ 'AUTO_pull_list_title': "Booking Pull List",
+ 'AUTO_interval_in_days': "Generate list for this many days hence: ",
+ 'AUTO_ATTR_VALUE_fetch': "Fetch",
+ 'AUTO_th_title_or_name': "Title or name",
+ 'AUTO_th_barcode': "Barcode",
+ 'AUTO_th_call_number': "Call number",
+ 'AUTO_th_copy_location': "Copy location",
+ 'AUTO_th_copy_number': "Copy number",
+ 'AUTO_th_resv_details': "Reservation details",
+ 'AUTO_ATTR_VALUE_print': "Print",
+}
Modified: trunk/Open-ILS/web/js/dojo/openils/booking/nls/reservation.js
===================================================================
--- trunk/Open-ILS/web/js/dojo/openils/booking/nls/reservation.js 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/web/js/dojo/openils/booking/nls/reservation.js 2009-12-30 15:43:32 UTC (rev 15247)
@@ -45,6 +45,8 @@
"Error retrieving booking resource type",
'INVALID_TS_RANGE':
"You must choose a valid start and end time for the reservation.",
+ 'BRSRC_NOT_FOUND': "Could not locate that resource.",
+ 'BRSRC_RETRIVE_ERROR': "Error retrieving resource: ",
'ANY': "ANY",
'AUTO_choose_a_brt': "Choose a Bookable Resource Type",
@@ -62,5 +64,12 @@
'AUTO_bresv_grid_resource': "Resource",
'AUTO_bresv_grid_start_time': "Start time",
'AUTO_bresv_grid_end_time': "End time",
- 'AUTO_brt_noncat_only': "Show only non-cataloged bookable resource types"
+ 'AUTO_brt_noncat_only': "Show only non-cataloged bookable resource types",
+ 'AUTO_arbitrary_resource':
+ "Enter the barcode of a cataloged, bookable resource:",
+ 'AUTO_explain_bookable':
+ "To reserve an item that is not yet registered as a bookable " +
+ "resource, find it in the catalog or under <em>Display Item</em>, and "+
+ "select <em>Make Item Bookable</em> or <em>Book Item Now</em> there.",
+ 'AUTO_or': '- Or -'
}
Added: trunk/Open-ILS/web/js/ui/default/booking/common.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/booking/common.js (rev 0)
+++ trunk/Open-ILS/web/js/ui/default/booking/common.js 2009-12-30 15:43:32 UTC (rev 15247)
@@ -0,0 +1,64 @@
+/* Quick and dirty way to localize some strings; not recommended for reuse.
+ * I'm sure dojo provides a better mechanism for this, but at the moment
+ * this is faster to implement anew than figuring out the Right way to do
+ * the same thing w/ dojo.
+ */
+function init_auto_l10n(el) {
+ function do_it(myel, cls) {
+ if (cls) {
+ var clss = cls.split(" ");
+ for (var k in clss) {
+ var parts = clss[k].match(/^AUTO_ATTR_([A-Z]+)_.+$/);
+ if (parts && localeStrings[clss[k]]) {
+ myel.setAttribute(
+ parts[1].toLowerCase(), localeStrings[clss[k]]
+ );
+ } else if (clss[k].match(/^AUTO_/) && localeStrings[clss[k]]) {
+ myel.innerHTML = localeStrings[clss[k]];
+ }
+ }
+ }
+ }
+
+ for (var i in el.attributes) {
+ if (el.attributes[i].nodeName == "class") {
+ do_it(el, el.attributes[i].value);
+ break;
+ }
+ }
+ for (var i in el.childNodes) {
+ if (el.childNodes[i].nodeType == 1) { // element node?
+ init_auto_l10n(el.childNodes[i]); // recurse!
+ }
+ }
+}
+
+function get_keys(L) { var K = []; for (var k in L) K.push(k); return K; }
+function hide_dom_element(e) { e.style.display = "none"; };
+function reveal_dom_element(e) { e.style.display = ""; };
+function formal_name(u) {
+ var name = u.family_name() + ", " + u.first_given_name();
+ if (u.second_given_name())
+ name += (" " + u.second_given_name());
+ return name;
+}
+function humanize_timestamp_string(ts) {
+ /* For now, this discards time zones. */
+ var parts = ts.split("T");
+ var timeparts = parts[1].split("-")[0].split(":");
+ return parts[0] + " " + timeparts[0] + ":" + timeparts[1];
+}
+function is_ils_error(e) { return (e.ilsevent != undefined); }
+function is_ils_actor_card_error(e) {
+ return (e.textcode == "ACTOR_CARD_NOT_FOUND");
+}
+function my_ils_error(leader, e) {
+ var s = leader + "\n";
+ var keys = [
+ "ilsevent", "desc", "textcode", "servertime", "pid", "stacktrace"
+ ];
+ for (var i in keys) {
+ if (e[keys[i]]) s += ("\t" + keys[i] + ": " + e[keys[i]] + "\n");
+ }
+ return s;
+}
Added: trunk/Open-ILS/web/js/ui/default/booking/pull_list.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/booking/pull_list.js (rev 0)
+++ trunk/Open-ILS/web/js/ui/default/booking/pull_list.js 2009-12-30 15:43:32 UTC (rev 15247)
@@ -0,0 +1,190 @@
+dojo.require("openils.User");
+dojo.require("openils.PermaCrud");
+dojo.require("fieldmapper.OrgUtils");
+dojo.require("openils.widget.OrgUnitFilteringSelect");
+dojo.requireLocalization("openils.booking", "pull_list");
+
+var localeStrings = dojo.i18n.getLocalization("openils.booking", "pull_list");
+var pcrud = new openils.PermaCrud();
+
+var pickup_lib_selected;
+var acp_cache = {};
+
+function init_pickup_lib_selector() {
+ var User = new openils.User();
+ User.buildPermOrgSelector(
+ "RETRIEVE_RESERVATION_PULL_LIST", pickup_lib_selector, null,
+ function() {
+ pickup_lib_selected = pickup_lib_selector.getValue();
+ dojo.connect(pickup_lib_selector, "onChange",
+ function() { pickup_lib_selected = this.getValue(); }
+ )
+ }
+ );
+}
+
+function retrieve_pull_list(ivl_in_days) {
+ var secs = Number(ivl_in_days) * 86400;
+
+ if (isNaN(secs) || secs < 1)
+ throw new Error("Invalid interval");
+
+ return fieldmapper.standardRequest(
+ ["open-ils.booking", "open-ils.booking.reservations.get_pull_list"],
+ [xulG.auth.session.key, null, secs, pickup_lib_selected]
+ );
+}
+
+function dom_table_rowid(resource_id) {
+ return "pull_list_resource_" + resource_id;
+}
+
+function generate_result_row(one) {
+ function cell(id, content) {
+ var td = document.createElement("td");
+ if (id != undefined) td.setAttribute("id", id);
+ td.appendChild(document.createTextNode(content));
+ return td;
+ }
+
+ function reservation_info_cell(one) {
+ var td = document.createElement("td");
+ for (var i in one.reservations) {
+ var one_resv = one.reservations[i];
+ var div = document.createElement("div");
+ var s = humanize_timestamp_string(one_resv.start_time()) + " - " +
+ humanize_timestamp_string(one_resv.end_time()) + " " +
+ formal_name(one_resv.usr());
+ /* FIXME: The above need patron barcode instead of name, but
+ * that requires a fix in the middle layer to flesh on the
+ * right stuff. */
+ div.appendChild(document.createTextNode(s));
+ td.appendChild(div);
+ }
+ return td;
+ }
+
+ var baseid = dom_table_rowid(one.current_resource.id());
+
+ var cells = [];
+ cells.push(cell(undefined, one.target_resource_type.name()));
+ cells.push(cell(undefined, one.current_resource.barcode()));
+ cells.push(cell(baseid + "_call_number", "-"));
+ cells.push(cell(baseid + "_copy_location", "-"));
+ cells.push(cell(baseid + "_copy_number", "-"));
+ cells.push(reservation_info_cell(one));
+
+ var row = document.createElement("tr");
+ row.setAttribute("id", baseid);
+
+ for (var i in cells) row.appendChild(cells[i]);
+ return row;
+}
+
+function render_pull_list_fundamentals(list) {
+ var rows = [];
+
+ for (var i in list)
+ rows.push(generate_result_row(list[i]));
+
+ document.getElementById("the_table_body").innerHTML = "";
+
+ for (var i in rows)
+ document.getElementById("the_table_body").appendChild(rows[i]);
+}
+
+function get_all_relevant_acp(list) {
+ var barcodes = [];
+ for (var i in list) {
+ if (list[i].target_resource_type.catalog_item()) {
+ /* There shouldn't be any duplicates. No need to worry bout that */
+ barcodes.push(list[i].current_resource.barcode());
+ }
+ }
+ var results = fieldmapper.standardRequest(
+ [
+ "open-ils.booking",
+ "open-ils.booking.asset.get_copy_fleshed_just_right"
+ ],
+ [xulG.auth.session.key, barcodes]
+ );
+
+ if (!results) {
+ alert(localeStrings.COPY_LOOKUP_NO_RESPONSE);
+ return null;
+ } else if (is_ils_error(results)) {
+ alert(my_ils_error(localeStrings.COPY_LOOKUP_ERROR, results));
+ return null;
+ } else {
+ return results;
+ }
+}
+
+function fill_in_pull_list_details(list, acp_cache) {
+ for (var i in list) {
+ var one = list[i];
+ if (one.target_resource_type.catalog_item() == "t") {
+ /* FIXME: This block could stand to be a lot more elegant. */
+ var call_number_el = document.getElementById(
+ dom_table_rowid(one.current_resource.id()) + "_call_number"
+ );
+ var copy_location_el = document.getElementById(
+ dom_table_rowid(one.current_resource.id()) + "_copy_location"
+ );
+ var copy_number_el = document.getElementById(
+ dom_table_rowid(one.current_resource.id()) + "_copy_number"
+ );
+
+ var bc = one.current_resource.barcode();
+
+ if (acp_cache[bc]) {
+ if (call_number_el && acp_cache[bc].call_number()) {
+ var value = acp_cache[bc].call_number().label();
+ if (value) call_number_el.innerHTML = value;
+ }
+ if (copy_location_el && acp_cache[bc].location()) {
+ var value = acp_cache[bc].location().name();
+ if (value) copy_location_el.innerHTML = value;
+ }
+ if (copy_number_el) {
+ var value = acp_cache[bc].copy_number();
+ if (value) copy_number_el.innerHTML = value;
+ }
+ } else {
+ alert(localeStrings.COPY_MISSING + bc);
+ }
+ }
+ }
+}
+
+function populate_pull_list(form) {
+ /* Step 1: get the pull list from the server. */
+ try {
+ var results = retrieve_pull_list(form.interval_in_days.value);
+ } catch (E) {
+ alert(localeStrings.PULL_LIST_ERROR + E);
+ return;
+ }
+ if (results == null) {
+ alert(localeStrings.PULL_LIST_NO_RESPONSE);
+ return;
+ } else if (is_ils_error(results)) {
+ alert(my_ils_error(localeStrings.PULL_LIST_ERROR, results));
+ return;
+ }
+
+ /* Step 2: render the table with the pull list */
+ render_pull_list_fundamentals(results);
+
+ /* Step 3: asynchronously fill in the copy details we're missing */
+ setTimeout(function() {
+ var acp_cache = {};
+ if ((acp_cache = get_all_relevant_acp(results)))
+ fill_in_pull_list_details(results, acp_cache);
+ }, 0);
+}
+
+function my_init() {
+ init_pickup_lib_selector();
+ init_auto_l10n(document.getElementById("auto_l10n_start_here"));
+}
Modified: trunk/Open-ILS/web/js/ui/default/booking/reservation.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/booking/reservation.js 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/web/js/ui/default/booking/reservation.js 2009-12-30 15:43:32 UTC (rev 15247)
@@ -15,6 +15,7 @@
var pcrud = new openils.PermaCrud();
var opts;
var our_brt;
+var brt_list = [];
var brsrc_index = {};
var bresv_index = {};
var just_reserved_now = {};
@@ -184,21 +185,6 @@
/*
* Misc helper functions
*/
-function hide_dom_element(e) { e.style.display = "none"; };
-function reveal_dom_element(e) { e.style.display = ""; };
-function get_keys(L) { var K = []; for (var k in L) K.push(k); return K; }
-function formal_name(u) {
- var name = u.family_name() + ", " + u.first_given_name();
- if (u.second_given_name())
- name += (" " + u.second_given_name());
- return name;
-}
-function humanize_timestamp_string(ts) {
- /* For now, this discards time zones. */
- var parts = ts.split("T");
- var timeparts = parts[1].split("-")[0].split(":");
- return parts[0] + " " + timeparts[0] + ":" + timeparts[1];
-}
function set_datagrid_empty_store(grid) {
grid.setStore(
new dojo.data.ItemFileReadStore(
@@ -206,20 +192,6 @@
)
);
}
-function is_ils_error(e) { return (e.ilsevent != undefined); }
-function is_ils_actor_card_error(e) {
- return (e.textcode == "ACTOR_CARD_NOT_FOUND");
-}
-function my_ils_error(header, e) {
- var s = header + "\n";
- var keys = [
- "ilsevent", "desc", "textcode", "servertime", "pid", "stacktrace"
- ];
- for (var i in keys) {
- if (e[keys[i]]) s += ("\t" + keys[i] + ": " + e[keys[i]] + "\n");
- }
- return s;
-}
/*
* These functions communicate with the middle layer.
@@ -484,6 +456,27 @@
);
}
+function munge_specific_resource(barcode) {
+ try {
+ var brsrc_list = pcrud.search('brsrc', {'barcode': barcode});
+ if (brsrc_list && brsrc_list.length > 0) {
+ opts.booking_results = {
+ "brt": [[brsrc_list[0].type(), 0, 1]],
+ "brsrc": [[brsrc_list[0].id(), 0, 1]],
+ };
+ if (!(our_brt = get_brt_by_id(opts.booking_results.brt[0][0]))) {
+ alert(localeStrings.COULD_NOT_RETRIEVE_BRT_PASSED_IN);
+ } else {
+ init_reservation_interface();
+ }
+ } else {
+ alert(localeStrings.BRSRC_NOT_FOUND);
+ }
+ } catch (E) {
+ alert(localeStrings.BRSRC_RETRIEVE_ERROR + E);
+ }
+}
+
/*
* These functions deal with interface tricks (populating widgets,
* changing the page, etc.).
@@ -492,14 +485,10 @@
if (!targ_div) {
alert(localeStrings.NO_TARG_DIV);
} else {
- var brt_list = xulG.brt_list = get_all_noncat_brt();
+ brt_list = get_all_noncat_brt();
if (!brt_list || brt_list.length < 1) {
- targ_div.appendChild(
- document.createTextNode(localeStrings.NO_BRT_RESULTS)
- );
- document.getElementById(
- "brt_select_other_controls"
- ).style.display = "none";
+ document.getElementById("select_noncat_brt_block").
+ style.display = "none";
} else {
var selector = document.createElement("select");
selector.setAttribute("id", "brt_selector");
@@ -520,17 +509,29 @@
}
}
-function init_reservation_interface(f) {
+function init_resv_iface_arb() {
+ init_reservation_interface(document.getElementById("arbitrary_resource"));
+}
+
+function init_resv_iface_sel() {
+ init_reservation_interface(document.getElementById("brt_selector"));
+}
+
+function init_reservation_interface(widget) {
+ /* Save a global reference to the brt we're going to reserve */
+ if (widget && (widget.selectedIndex != undefined)) {
+ our_brt = brt_list[widget.selectedIndex];
+ } else if (widget != undefined) {
+ if (!munge_specific_resource(widget.value))
+ return;
+ }
+
/* Hide and reveal relevant divs. */
var search_block = document.getElementById("brt_search_block");
var reserve_block = document.getElementById("brt_reserve_block");
hide_dom_element(search_block);
reveal_dom_element(reserve_block);
- /* Save a global reference to the brt we're going to reserve */
- if (f)
- our_brt = xulG.brt_list[f.brt_selector.selectedIndex];
-
/* Get a list of attributes that can apply to that brt. */
var bra_list = pcrud.search("bra", {"resource_type": our_brt.id()});
if (!bra_list) {
@@ -587,12 +588,6 @@
/* Add a prominent label reminding the user what resource type they're
* asking about. */
document.getElementById("brsrc_list_header").innerHTML = our_brt.name();
-
- if (opts.patron_barcode) {
- document.getElementById("holds_patron_barcode").style.display = "none";
- document.getElementById("patron_barcode").value = opts.patron_barcode;
- document.getElementById("patron_barcode").onchange();
- }
update_brsrc_list();
}
@@ -702,41 +697,6 @@
}
}
-/* Quick and dirty way to localize some strings; not recommended for reuse.
- * I'm sure dojo provides a better mechanism for this, but at the moment
- * this is faster to implement anew than figuring out the Right way to do
- * the same thing w/ dojo.
- */
-function init_auto_l10n(el) {
- function do_it(myel, cls) {
- if (cls) {
- var clss = cls.split(" ");
- for (var k in clss) {
- var parts = clss[k].match(/^AUTO_ATTR_([A-Z]+)_.+$/);
- if (parts && localeStrings[clss[k]]) {
- myel.setAttribute(
- parts[1].toLowerCase(), localeStrings[clss[k]]
- );
- } else if (clss[k].match(/^AUTO_/) && localeStrings[clss[k]]) {
- myel.innerHTML = localeStrings[clss[k]];
- }
- }
- }
- }
-
- for (var i in el.attributes) {
- if (el.attributes[i].nodeName == "class") {
- do_it(el, el.attributes[i].value);
- break;
- }
- }
- for (var i in el.childNodes) {
- if (el.childNodes[i].nodeType == 1) { // element node?
- init_auto_l10n(el.childNodes[i]); // recurse!
- }
- }
-}
-
/* The following function should return true if the reservation interface
* should start normally (show a list of brt to choose from) or false if
* it should not (because we've "started" it some other way by setting up
@@ -757,16 +717,9 @@
}
if (opts.patron_barcode) {
- try {
- var patron = get_actor_by_barcode(opts.patron_barcode);
- if (patron) {
- document.getElementById("preselected_patron").innerHTML =
- "Patron targeted for reservation: <strong>" +
- formal_name(patron) + "</strong>";
- }
- } catch (E) {
- ; /* XXX ignorable? perhaps. */
- }
+ document.getElementById("contain_patron_barcode").style.display="none";
+ document.getElementById("patron_barcode").value = opts.patron_barcode;
+ update_bresv_grid();
}
return true;
Modified: trunk/Open-ILS/web/opac/locale/en-US/lang.dtd
===================================================================
--- trunk/Open-ILS/web/opac/locale/en-US/lang.dtd 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/web/opac/locale/en-US/lang.dtd 2009-12-30 15:43:32 UTC (rev 15247)
@@ -765,6 +765,8 @@
<!ENTITY staff.main.menu.booking.accesskey "B">
<!ENTITY staff.main.menu.booking.reservation.label "Create or Edit Reservations">
<!ENTITY staff.main.menu.booking.reservation.accesskey "C">
+<!ENTITY staff.main.menu.booking.pull_list.label "Pull List">
+<!ENTITY staff.main.menu.booking.pull_list.accesskey "L">
<!ENTITY staff.main.menu.booking.reservation_pickup.label "Pick Up Reservations">
<!ENTITY staff.main.menu.booking.reservation_pickup.accesskey "P">
<!ENTITY staff.main.menu.booking.reservation_return.label "Return Reservations">
Added: trunk/Open-ILS/web/templates/default/booking/pull_list.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/booking/pull_list.tt2 (rev 0)
+++ trunk/Open-ILS/web/templates/default/booking/pull_list.tt2 2009-12-30 15:43:32 UTC (rev 15247)
@@ -0,0 +1,49 @@
+[% WRAPPER "default/base.tt2" %]
+<script src="[% ctx.media_prefix %]/js/ui/default/booking/common.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/booking/pull_list.js"></script>
+<link rel="stylesheet" type="text/css" href="[% ctx.media_prefix %]/css/skin/[% ctx.skin %]/booking.css" />
+<script type="text/javascript">openils.Util.addOnLoad(my_init);</script>
+<div id="auto_l10n_start_here">
+ <h1 class="booking AUTO_pull_list_title"></h1>
+ <form onsubmit="populate_pull_list(this); return false;">
+ <div id="pickup_lib_selector_row" class="nice_vertical_padding">
+ <label for="pickup_lib_selector" class="AUTO_pickup_lib_selector">
+ </label>
+ <select dojoType="openils.widget.OrgUnitFilteringSelect"
+ id="pickup_lib_selector" jsId="pickup_lib_selector"
+ searchAttr="shortname" labelAttr="shortname"></select>
+ </div>
+ <div id="interval_input_row" class="nice_vertical_padding">
+ <label for="interval_in_days" class="AUTO_interval_in_days"></label>
+
+ <!-- XXX Hardcoded values (like the ones below) are bad. -->
+ <input id="interval_in_days" name="interval_in_days"
+ value="5" maxlength="2" />
+
+ </div>
+ <input type="submit" class="AUTO_ATTR_VALUE_fetch" />
+ </form>
+ <hr />
+ <div id="table_goes_here" class="nice_vertical_padding">
+ <table id="the_table" width="90%">
+ <thead>
+ <tr>
+ <th width="30%" class="AUTO_th_title_or_name"></th>
+ <th width="10%" class="AUTO_th_barcode"></th>
+ <th width="10%" class="AUTO_th_call_number"></th>
+ <th width="10%" class="AUTO_th_copy_location"></th>
+ <th width="10%" class="AUTO_th_copy_number"></th>
+ <th width="30%" class="AUTO_th_resv_details"></th>
+ </tr>
+ </thead>
+ <tbody id="the_table_body">
+ </tbody>
+ </table>
+ </div>
+ <div id="print_holder" class="nice_vertical_padding">
+ <!-- XXX Print button probably won't stay right here -->
+ <input type="button" class="AUTO_ATTR_VALUE_print"
+ onclick="window.print();" /><!-- XXX too simplistic? -->
+ </div>
+</div>
+[% END %]
Modified: trunk/Open-ILS/web/templates/default/booking/reservation.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/booking/reservation.tt2 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/web/templates/default/booking/reservation.tt2 2009-12-30 15:43:32 UTC (rev 15247)
@@ -1,4 +1,5 @@
[% WRAPPER "default/base.tt2" %]
+<script src="[% ctx.media_prefix %]/js/ui/default/booking/common.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/booking/reservation.js"></script>
<link rel="stylesheet" type="text/css" href="[% ctx.media_prefix %]/css/skin/[% ctx.skin %]/booking.css" />
<script type="text/javascript">
@@ -8,26 +9,31 @@
<div id="auto_l10n_start_here">
<div id="brt_search_block" class="container">
<h1 class="booking AUTO_choose_a_brt"></h1>
- <form onsubmit="init_reservation_interface(this); return false;">
- <div id="brt_selector_here" class="nice_vertical_padding"></div>
- <div id="brt_select_other_controls">
- <!-- <div class="nice_vertical_padding">
- <input type="checkbox" name="brt_noncat_only"
- id="brt_noncat_only" checked="checked" />
- <label for="brt_noncat_only"
- class="AUTO_brt_noncat_only"></label>
- </div> -->
+ <form onsubmit="return false;">
+ <div id="select_noncat_brt_block">
+ <div id="brt_selector_here" class="nice_vertical_padding"></div>
<div class="nice_vertical_padding">
- <input type="submit"
- class="AUTO_ATTR_VALUE_next" />
+ <input type="button" class="AUTO_ATTR_VALUE_next"
+ onclick="init_resv_iface_sel(); return false"
+ />
</div>
+ <hr />
+ <div class="nice_vertical_padding AUTO_or" id="or"></div>
</div>
+ <div id="arbitrary_resource_block">
+ <label for="arbitrary_resource" class="AUTO_arbitrary_resource">
+ </label>
+ <input id="arbitrary_resource" name="arbitrary_resource" />
+ <input type="button"
+ onclick="init_resv_iface_arb(); return false;"
+ class="AUTO_ATTR_VALUE_next" />
+ <p class="AUTO_explain_bookable"></p>
+ </div>
</form>
- <div id="preselected_patron"></div>
</div>
<div id="brt_reserve_block" class="container">
- <form>
+ <form onsubmit="return false;">
<div id="brsrc_available_outer">
<h1 class="booking" id="brsrc_list_header"></h1>
<!-- I'm reluctantly hardcoding the size attribute below to 12
@@ -35,7 +41,7 @@
anything in CSS. -->
<select id="brsrc_list" name="brsrc_list" multiple="multiple"
size="12"></select>
- <div id="holds_patron_barcode" class="nice_vertical_padding">
+ <div id="contain_patron_barcode" class="nice_vertical_padding">
<label class="AUTO_patron_barcode"
for="patron_barcode" /></label>
<input name="patron_barcode" id="patron_barcode"
@@ -71,34 +77,35 @@
class="booking AUTO_with_these_attr"></h2>
<div id="bra_and_brav"></div>
</div>
- <div id="reserve_under">
- <hr />
- <h2 class="booking" id="existing_reservation_patron_line"></h2>
- <div id="bresv_grid_alt_explanation"></div>
- <table id="bresv_grid" jsId="bresvGrid"
- dojoType="dojox.grid.DataGrid" query="{id: '*'}"
- rowSelector="20px" autoHeight="true">
- <thead>
- <tr><!-- FIXME: i18n problem: init_auto_l10n() runs
- too late to take care of the below elements. -->
- <th field="type">Type</th>
- <th field="resource">Resource</th>
- <th field="start_time">Start time</th>
- <th field="end_time">End time</th>
- </tr>
- </thead>
- </table>
- <div class="nice_vertical_padding"
- id="existing_bresv_under_buttons">
- <input type="button" id="button_edit_existing"
- class="AUTO_ATTR_VALUE_button_edit_existing"
- disabled="disabled" />
- <input type="button" id="button_cancel_existing"
- class="AUTO_ATTR_VALUE_button_cancel_existing"
- onclick="cancel_selected_bresv(bresvGrid.selection.getSelected());" />
- </div>
- </div>
</form>
</div>
+
+ <div id="reserve_under">
+ <hr />
+ <h2 class="booking" id="existing_reservation_patron_line"></h2>
+ <div id="bresv_grid_alt_explanation"></div>
+ <table id="bresv_grid" jsId="bresvGrid"
+ dojoType="dojox.grid.DataGrid" query="{id: '*'}"
+ rowSelector="20px" autoHeight="true" width="auto">
+ <thead>
+ <tr><!-- FIXME: i18n problem: init_auto_l10n() runs
+ too late to take care of the below elements. -->
+ <th width="35%" field="type">Type</th>
+ <th width="25%" field="resource">Resource</th>
+ <th width="20%" field="start_time">Start time</th>
+ <th width="20%" field="end_time">End time</th>
+ </tr>
+ </thead>
+ </table>
+ <div class="nice_vertical_padding"
+ id="existing_bresv_under_buttons">
+ <input type="button" id="button_edit_existing"
+ class="AUTO_ATTR_VALUE_button_edit_existing"
+ disabled="disabled" />
+ <input type="button" id="button_cancel_existing"
+ class="AUTO_ATTR_VALUE_button_cancel_existing"
+ onclick="cancel_selected_bresv(bresvGrid.selection.getSelected());" />
+ </div>
+ </div>
</div>
[% END %]
Modified: trunk/Open-ILS/xul/staff_client/chrome/content/main/menu.js
===================================================================
--- trunk/Open-ILS/xul/staff_client/chrome/content/main/menu.js 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/xul/staff_client/chrome/content/main/menu.js 2009-12-30 15:43:32 UTC (rev 15247)
@@ -704,6 +704,21 @@
);
}
],
+ 'cmd_booking_pull_list' : [
+ ['oncommand'],
+ function() {
+ obj.set_tab(
+ "/eg/booking/pull_list",
+ {
+ "tab_name": offlineStrings.getString(
+ "menu.cmd_booking_pull_list.tab"
+ ),
+ "browser": false
+ },
+ xulG
+ );
+ }
+ ],
'cmd_booking_reservation_pickup' : [
['oncommand'],
function() {
@@ -711,7 +726,7 @@
"/eg/booking/reservation_pickup",
{
"tab_name": offlineStrings.getString(
- "menu.cmd_booking_reservation.tab"
+ "menu.cmd_booking_reservation_pickup.tab"
),
"browser": false
},
@@ -726,7 +741,7 @@
"/eg/booking/reservation_return",
{
"tab_name": offlineStrings.getString(
- "menu.cmd_booking_reservation.tab"
+ "menu.cmd_booking_reservation_return.tab"
),
"browser": false
},
Modified: trunk/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul
===================================================================
--- trunk/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/xul/staff_client/chrome/content/main/menu_frame_menus.xul 2009-12-30 15:43:32 UTC (rev 15247)
@@ -89,6 +89,7 @@
<command id="cmd_acq_view_distrib_formula" />
<command id="cmd_booking_reservation" />
+ <command id="cmd_booking_pull_list" />
<command id="cmd_booking_reservation_pickup" />
<command id="cmd_booking_reservation_return" />
@@ -264,6 +265,7 @@
<menu id="main.menu.booking" label="&staff.main.menu.booking.label;" accesskey="&staff.main.menu.booking.accesskey;">
<menupopup id="main.menu.booking.popup">
<menuitem label="&staff.main.menu.booking.reservation.label;" accesskey="&staff.main.menu.booking.reservation.accesskey;" command="cmd_booking_reservation"/>
+ <menuitem label="&staff.main.menu.booking.pull_list.label;" accesskey="&staff.main.menu.booking.pull_list.accesskey;" command="cmd_booking_pull_list"/>
<!-- <menuitem label="&staff.main.menu.booking.reservation_pickup.label;" accesskey="&staff.main.menu.booking.reservation_pickup.accesskey;" command="cmd_booking_reservation_pickup"/>
<menuitem label="&staff.main.menu.booking.reservation_return.label;" accesskey="&staff.main.menu.booking.reservation_return.accesskey;" command="cmd_booking_reservation_return"/> -->
</menupopup>
Modified: trunk/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties
===================================================================
--- trunk/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties 2009-12-30 15:43:32 UTC (rev 15247)
@@ -234,6 +234,9 @@
menu.cmd_acq_view_distrib_formula.tab=Distribution Formulas
menu.cmd_booking_resource.tab=Resources
menu.cmd_booking_reservation.tab=Reservations
+menu.cmd_booking_reservation_pickup.tab=Reservation Pickup
+menu.cmd_booking_reservation_return.tab=Reservation Return
+menu.cmd_booking_pull_list.tab=Booking Pull List
menu.local_admin.circ_matrix_matchpoint.tab=Circulation Policies
menu.local_admin.hold_matrix_matchpoint.tab=Hold Policies
menu.local_admin.work_log.tab=Work Log
Modified: trunk/Open-ILS/xul/staff_client/server/patron/display_horiz_overlay.xul
===================================================================
--- trunk/Open-ILS/xul/staff_client/server/patron/display_horiz_overlay.xul 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/xul/staff_client/server/patron/display_horiz_overlay.xul 2009-12-30 15:43:32 UTC (rev 15247)
@@ -86,19 +86,13 @@
<button id="PatronNavBar_edit" command="cmd_patron_edit" class="nav"
label="&staff.patron_navbar.edit;" accesskey="&staff.patron_navbar.edit.accesskey;"/>
<button id="PatronNavBar_messages" label="&staff.patron_navbar.actions.menu.standing_penalties.label;" accesskey="&staff.patron_navbar.actions.menu.standing_penalties.accesskey;" command="cmd_standing_penalties" class="nav"/>
-
- <button id="PatronNavBar_booking" command="cmd_patron_booking" class="nav" label="&staff.patron_navbar.booking;" accesskey="&staff.patron_navbar.booking.accesskey;" type="menu">
- <menupopup>
- <menuitem label="&staff.main.menu.booking.reservation.label;" accesskey="&staff.main.menu.booking.reservation.accesskey;" command="cmd_patron_reservation" />
- </menupopup>
- </button>
-
<button id="PatronNavBar_other" command="cmd_patron_other" class="nav" label="&staff.patron_navbar.other;" accesskey="&staff.patron_navbar.other.accesskey;" type="menu">
<menupopup>
<menuitem label="&staff.patron_navbar.alert;" accesskey="&staff.patron_navbar.alert.accesskey;" command="cmd_patron_alert"/>
<menuitem label="&staff.patron.info.notes.label;" accesskey="&staff.patron.info.notes.accesskey;" command="cmd_patron_info_notes"/>
<menuitem label="&staff.patron.info.triggered_events.label;" accesskey="&staff.patron.info.triggered_events.accesskey;" command="cmd_patron_info_triggered_events"/>
<menuitem label="&staff.patron.info.stat_cats.label;" accesskey="&staff.patron.info.stat_cats.accesskey;" command="cmd_patron_info_stats"/>
+ <menuitem label="&staff.main.menu.booking.reservation.label;" accesskey="&staff.main.menu.booking.reservation.accesskey;" command="cmd_patron_reservation" />
<menuitem label="&staff.patron.info.surveys.label;" accesskey="&staff.patron.info.surveys.accesskey;" command="cmd_patron_info_surveys"/>
<menuitem label="&staff.patron.info.group.label;" accesskey="&staff.patron.info.group.accesskey;" command="cmd_patron_info_groups"/>
<menuitem label="&staff.patron_display.verify_password.label;" accesskey="&staff.patron_display.verify_password.accesskey;" command="cmd_verify_credentials"/>
Modified: trunk/Open-ILS/xul/staff_client/server/patron/display_overlay.xul
===================================================================
--- trunk/Open-ILS/xul/staff_client/server/patron/display_overlay.xul 2009-12-30 15:24:33 UTC (rev 15246)
+++ trunk/Open-ILS/xul/staff_client/server/patron/display_overlay.xul 2009-12-30 15:43:32 UTC (rev 15247)
@@ -86,19 +86,13 @@
<button id="PatronNavBar_edit" command="cmd_patron_edit" class="nav"
label="&staff.patron_navbar.edit;" accesskey="&staff.patron_navbar.edit.accesskey;"/>
<button id="PatronNavBar_messages" label="&staff.patron_navbar.actions.menu.standing_penalties.label;" accesskey="&staff.patron_navbar.actions.menu.standing_penalties.accesskey;" command="cmd_standing_penalties" class="nav"/>
-
- <button id="PatronNavBar_booking" command="cmd_patron_booking" class="nav" label="&staff.patron_navbar.booking;" accesskey="&staff.patron_navbar.booking.accesskey;" type="menu">
- <menupopup>
- <menuitem label="&staff.main.menu.booking.reservation.label;" accesskey="&staff.main.menu.booking.reservation.accesskey;" command="cmd_patron_reservation" />
- </menupopup>
- </button>
-
<button id="PatronNavBar_other" command="cmd_patron_other" class="nav" label="&staff.patron_navbar.other;" accesskey="&staff.patron_navbar.other.accesskey;" type="menu">
<menupopup>
<menuitem label="&staff.patron_navbar.alert;" accesskey="&staff.patron_navbar.alert.accesskey;" command="cmd_patron_alert"/>
<menuitem label="&staff.patron.info.notes.label;" accesskey="&staff.patron.info.notes.accesskey;" command="cmd_patron_info_notes"/>
<menuitem label="&staff.patron.info.triggered_events.label;" accesskey="&staff.patron.info.triggered_events.accesskey;" command="cmd_patron_info_triggered_events"/>
<menuitem label="&staff.patron.info.stat_cats.label;" accesskey="&staff.patron.info.stat_cats.accesskey;" command="cmd_patron_info_stats"/>
+ <menuitem label="&staff.main.menu.booking.reservation.label;" accesskey="&staff.main.menu.booking.reservation.accesskey;" command="cmd_patron_reservation" />
<menuitem label="&staff.patron.info.surveys.label;" accesskey="&staff.patron.info.surveys.accesskey;" command="cmd_patron_info_surveys"/>
<menuitem label="&staff.patron.info.group.label;" accesskey="&staff.patron.info.group.accesskey;" command="cmd_patron_info_groups"/>
<menuitem label="&staff.patron_display.verify_password.label;" accesskey="&staff.patron_display.verify_password.accesskey;" command="cmd_verify_credentials"/>
More information about the open-ils-commits
mailing list