From 61ec223d8989c2a48017812dff2960bacc1ef0c5 Mon Sep 17 00:00:00 2001 From: senator Date: Tue, 23 Nov 2010 21:40:36 +0000 Subject: [PATCH] Serials: add ability to print routing lists from the batch receive interface git-svn-id: svn://svn.open-ils.org/ILS/trunk@18840 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../src/perlmods/OpenILS/Application/Serial.pm | 12 +- Open-ILS/web/js/dojo/openils/XUL.js | 21 ++- .../ui/default/serial/print_routing_list_users.js | 147 +++++++++++++++++++++ Open-ILS/web/opac/locale/en-US/lang.dtd | 2 + .../default/serial/print_routing_list_users.tt2 | 38 ++++++ .../server/locale/en-US/serial.properties | 1 + .../staff_client/server/serial/batch_receive.js | 97 +++++++++++++- .../server/serial/batch_receive_overlay.xul | 10 +- Open-ILS/xul/staff_client/server/skin/serial.css | 1 + 9 files changed, 314 insertions(+), 15 deletions(-) create mode 100644 Open-ILS/web/js/ui/default/serial/print_routing_list_users.js create mode 100644 Open-ILS/web/templates/default/serial/print_routing_list_users.tt2 diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm b/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm index 444429fa24..1393a2ae22 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Serial.pm @@ -2806,7 +2806,7 @@ __PACKAGE__->register_method( "(with card and home_ou) for a given stream ID, sorted by pos", "params" => [ {"desc" => "Authtoken", "type" => "string"}, - {"desc" => "Stream ID", "type" => "number"}, + {"desc" => "Stream ID (int or array of ints)", "type" => "mixed"}, ], "return" => { "desc" => "Stream of routing list users", "type" => "object", @@ -2818,8 +2818,6 @@ __PACKAGE__->register_method( sub get_routing_list_users { my ($self, $client, $auth, $stream_id) = @_; - return undef unless $stream_id = int $stream_id; # sic, assignment - my $e = new_editor("authtoken" => $auth); return $e->die_event unless $e->checkauth; @@ -2846,9 +2844,11 @@ sub get_routing_list_users { $e->disconnect; - # Now we can strip the stream/distribution info (only used for perm - # checking) and send back the srlu's to the caller. - $client->respond($_) for map { $_->stream($_->stream->id); $_ } @$users; + my @users = map { $_->stream($_->stream->id); $_ } @$users; + @users = sort { $a->stream cmp $b->stream } @users if + ref $stream_id eq "ARRAY"; + + $client->respond($_) for @users; undef; } diff --git a/Open-ILS/web/js/dojo/openils/XUL.js b/Open-ILS/web/js/dojo/openils/XUL.js index ec1e765e40..8e367dab4c 100644 --- a/Open-ILS/web/js/dojo/openils/XUL.js +++ b/Open-ILS/web/js/dojo/openils/XUL.js @@ -36,7 +36,9 @@ if(!dojo._hasResource["openils.XUL"]) { xulG.new_tab(path, tabInfo, options); } - openils.XUL.newTabEasy = function(url, tab_name, extra_content_params) { + openils.XUL.newTabEasy = function( + url, tab_name, extra_content_params, wrap_in_browser + ) { var content_params = { "session": openils.User.authtoken, "authtime": openils.User.authtime @@ -52,9 +54,20 @@ if(!dojo._hasResource["openils.XUL"]) { if (extra_content_params) dojo.mixin(content_params, extra_content_params); - xulG.new_tab( - xulG.url_prefix(url), {"tab_name": tab_name}, content_params - ); + var loc = xulG.url_prefix(url); + + if (wrap_in_browser) { + loc = urls.XUL_BROWSER + "?url=" + window.escape(loc); + content_params = dojo.mixin( + { + "no_xulG": false, "show_print_button": true, + "show_nav_buttons": true, + "passthru_content_params": extra_content_params + }, content_params + ); + } + + xulG.new_tab(loc, {"tab_name": tab_name}, content_params); }; /** diff --git a/Open-ILS/web/js/ui/default/serial/print_routing_list_users.js b/Open-ILS/web/js/ui/default/serial/print_routing_list_users.js new file mode 100644 index 0000000000..014f6451d7 --- /dev/null +++ b/Open-ILS/web/js/ui/default/serial/print_routing_list_users.js @@ -0,0 +1,147 @@ +dojo.require("dojo.string"); + +var list_renderer; + +function n(name, ctx) { return dojo.query("[name='" + name + "']", ctx)[0]; } + +function ListRenderer() { + var self = this; + + this.render = function() { + for (var i = 0; i < this.streams.length; i++) { + var stream = this.streams[i]; + var list = dojo.clone(this.list_template); + n("title", list).innerHTML = this.mvr.title(); + n("issuance_label", list).innerHTML = this.issuance.label(); + n("distribution_holding_lib", list).innerHTML = + stream.distribution().holding_lib().shortname(); + n("distribution_label", list).innerHTML = + stream.distribution().label(); + if (stream.routing_label()) { + n("stream_routing_label", list).innerHTML = + stream.routing_label(); + openils.Util.show( + n("stream_routing_label", list), "inline" + ); + } else { + n("stream_id", list).innerHTML = stream.id(); + openils.Util.show(n("stream_id_container", list), "inline"); + } + + this.render_users(stream, list); + + if (i) { + dojo.create( + "hr", + {"style": "page-break-after: always"}, this.target, "last" + ); + } + + dojo.place(list, this.target, "last"); + } + + return this; /* for chaining */ + }; + + this.render_users = function(stream, list) { + for (var i = 0; i < this.users_by_stream[stream.id()].length; i++) { + var user = this.users_by_stream[stream.id()][i]; + var node = dojo.clone(this.user_template); + + if (user.reader()) { + n("barcode", node).innerHTML = user.reader().card().barcode(); + n("name", node).innerHTML = dojo.string.substitute( + "${0}, ${1} ${2}", [ + user.reader().family_name(), + user.reader().first_given_name(), + user.reader().second_given_name() + ].map(function(n) { return n || ""; }) + ); + n("ou", node).innerHTML = user.reader().home_ou().shortname(); + openils.Util.show(n("reader_container", node), "inline"); + } else if (user.department()) { + n("department", node).innerHTML = user.department(); + openils.Util.show(n("department_container", node), "inline"); + } + + if (user.note()) { + n("note", node).innerHTML = user.note(); + openils.Util.show(n("note_container", node), "inline"); + } + + dojo.place(node, n("users", list), "last"); + } + }; + + this.print = function() { + this.print_target.print(); + } + + this._sort_users = function() { + this.users_by_stream = {}; + this.users.forEach( + function(user) { + var key = user.stream(); + if (!self.users_by_stream[key]) + self.users_by_stream[key] = []; + self.users_by_stream[key].push(user); + } + ); + }; + + /* Unfortunately, when we print the main window with dijits + * wrapping everything, the page-break-* CSS properties don't work + * inside of there, so we need an iframe to print from. + */ + this._prepare_iframe = function() { + var iframe = dojo.create( + "iframe", { + "src": "", "width": "100%", "height": "500", "frameborder": 0 + }, "iframe_in_here", "only" + ); + + iframe.contentWindow.document.open(); + iframe.contentWindow.document.write( + "\n" + ); + iframe.contentWindow.document.close(); + this.target = iframe.contentWindow.document.body; + this.print_target = iframe.contentWindow; + }; + + this._init = function(data) { + this.user_template = dojo.byId("user_template"); + this.user_template.removeAttribute("id"); + this.user_template.parentNode.removeChild(this.user_template); + + this.list_template = dojo.byId("list_template"); + this.list_template.removeAttribute("id"); + this.list_template.parentNode.removeChild(this.list_template); + + dojo.mixin(this, data); + + this._sort_users(); + this._prepare_iframe(); + } + + this._init.apply(this, arguments); +} + +openils.Util.addOnLoad( + function() { + if (!xulG) { + alert( + "This interface is not designed for use outside " + + "the staff client." /* XXX i18n */ + ); + } else { + list_renderer = new ListRenderer(xulG.routing_list_data); + list_renderer.render().print(); + } + } +); diff --git a/Open-ILS/web/opac/locale/en-US/lang.dtd b/Open-ILS/web/opac/locale/en-US/lang.dtd index c0e49b5933..28cc0b93e6 100644 --- a/Open-ILS/web/opac/locale/en-US/lang.dtd +++ b/Open-ILS/web/opac/locale/en-US/lang.dtd @@ -1655,6 +1655,8 @@ + + diff --git a/Open-ILS/web/templates/default/serial/print_routing_list_users.tt2 b/Open-ILS/web/templates/default/serial/print_routing_list_users.tt2 new file mode 100644 index 0000000000..c96da8353f --- /dev/null +++ b/Open-ILS/web/templates/default/serial/print_routing_list_users.tt2 @@ -0,0 +1,38 @@ +[% WRAPPER default/base.tt2 %] +[% ctx.page_title = "Serial Routing List" %] + +
+ +
+
+ +[% END %] diff --git a/Open-ILS/xul/staff_client/server/locale/en-US/serial.properties b/Open-ILS/xul/staff_client/server/locale/en-US/serial.properties index 9df704562f..cda2389b69 100644 --- a/Open-ILS/xul/staff_client/server/locale/en-US/serial.properties +++ b/Open-ILS/xul/staff_client/server/locale/en-US/serial.properties @@ -85,6 +85,7 @@ batch_receive.receive_time_note=Receive-time Note batch_receive.cn_for_lib=Do you want to use this call number at %1$s?\nIt doesn't exist there, and it will have to be created. batch_receive.missing_units=You have not provided barcodes and call numbers for all of the selected items. Choose OK to receive those items anyway, or choose Cancel to supply the missing information. batch_receive.missing_cn=You cannot assign a barcode without selecting a call number. Please correct the non-conforming units. +batch_receive.print_routing_list_users=Print Routing List pattern_wizard.enumeration.a=First level pattern_wizard.enumeration.b=Second level pattern_wizard.enumeration.c=Third level diff --git a/Open-ILS/xul/staff_client/server/serial/batch_receive.js b/Open-ILS/xul/staff_client/server/serial/batch_receive.js index 83891662dc..7cd5137b7b 100644 --- a/Open-ILS/xul/staff_client/server/serial/batch_receive.js +++ b/Open-ILS/xul/staff_client/server/serial/batch_receive.js @@ -4,6 +4,7 @@ dojo.require("dojo.cookie"); dojo.require("openils.Util"); dojo.require("openils.User"); dojo.require("openils.CGI"); +dojo.require("openils.XUL"); dojo.require("openils.PermaCrud"); var batch_receiver; @@ -56,6 +57,7 @@ function BatchReceiver() { this._prepared_call_number_controls = {}; this._location_by_lib = {}; this._copy_template_cache = {}; + this._wants_print_routing = {}; /* empty the entry receiving table if we're starting over */ if (this.item_cache) { @@ -346,20 +348,37 @@ function BatchReceiver() { return menulist; }; + this._build_print_routing_toggle = function(item) { + var start = true; + var checkbox = dojo.create( + "checkbox", { + "oncommand": function(ev) { + self._print_routing(item.id(), ev.target.checked); + }, + "checked": start.toString() + } + ); + this._print_routing(item.id(), start); + return checkbox; + } + this._build_receive_toggle = function(item) { return dojo.create( "checkbox", { "oncommand": function(ev) { self._disable_row(item.id(), !ev.target.checked); }, - "checked": "true" + "checked": "true", + "name": "receive_" + item.id() } ); } this._disable_row = function(item_id, disabled) { var row = this.rows[item_id]; - dojo.query("textbox,menulist", row).forEach( + dojo.query( + "textbox,menulist,checkbox:not([name^='receive_'])", row + ).forEach( function(element) { element.disabled = disabled; } ); this._row_disabled(row, disabled); @@ -368,7 +387,7 @@ function BatchReceiver() { this._row_disabled = function(row, disabled) { if (typeof(row) == "string") row = this.rows[row]; - var checkbox = dojo.query("checkbox", row)[0]; + var checkbox = dojo.query("checkbox", row)[1]; if (typeof(disabled) != "undefined") checkbox.checked = !disabled; @@ -376,6 +395,19 @@ function BatchReceiver() { return !checkbox.checked; }; + this._row_print_routing_disabled = function(row, disabled) { + if (typeof(row) == "string") row = this.rows[row]; + + var checkbox = dojo.query("checkbox", row)[0]; + + if (typeof(disabled) != "undefined") { + checkbox.checked = !disabled; + checkbox.doCommand(); + } + + return !checkbox.checked; + }; + this._row_field_value = function(row, field, value) { if (typeof(row) == "string") row = this.rows[row]; @@ -395,6 +427,10 @@ function BatchReceiver() { } } + this._print_routing = function(id, value) { + this._wants_print_routing[id] = value; + }; + this._user_wants_autogen = function() { return dojo.byId("autogen_barcodes").checked; }; @@ -511,6 +547,32 @@ function BatchReceiver() { } }; + this.print_routing_lists = function(streams) { + fieldmapper.standardRequest( + ["open-ils.serial", + "open-ils.serial.routing_list_users.fleshed_and_ordered.atomic"],{ + "params": [ + this.authtoken, streams.map(function(o) { return o.id(); }) + ], + "async": false, + "oncomplete": function(r) { + if ((r = openils.Util.readResponse(r)) && r.length) { + openils.XUL.newTabEasy( + "/eg/serial/print_routing_list_users", + S("print_routing_list_users"), { + "show_print_button": false, /* we supply one */ + "routing_list_data": { + "streams": streams, "mvr": self.bibdata.mvr, + "issuance": self.issuance, "users": r + } + }, true /* wrap_in_browser */ + ); + } + } + } + ); + }; + this.bib_lookup = function(bib_search_term, evt, is_actual_id, sub_id) { if (evt && evt.keyCode != 13) return; @@ -791,6 +853,12 @@ function BatchReceiver() { } }; + this.toggle_all_print_routing = function(checked) { + for (var id in this.rows) { + this._row_print_routing_disabled(id, !checked); + } + }; + this.build_batch_entry_row = function() { var row = dojo.byId("entry_batch_row"); @@ -820,6 +888,17 @@ function BatchReceiver() { this.batch_controls.price = dojo.create("textbox", {"size": 9}) ); + node_by_name("print_routing", row).appendChild( + dojo.create( + "checkbox", { + "oncommand": function(ev) { + self.toggle_all_print_routing(ev.target.checked); + }, + "checked": "true" + } + ) + ); + node_by_name("receive", row).appendChild( dojo.create( "checkbox", { @@ -896,6 +975,7 @@ function BatchReceiver() { n("circ_modifier").appendChild(this._build_circ_modifier_dropdown()); n("call_number").appendChild(this._build_call_number_control(item)); n("price").appendChild(dojo.create("textbox", {"size": 9})); + n("print_routing").appendChild(this._build_print_routing_toggle(item)); n("receive").appendChild(this._build_receive_toggle(item)); this.entry_tbody.appendChild(row); @@ -966,8 +1046,17 @@ function BatchReceiver() { "async": true, "oncomplete": function(r) { try { - while (item_id = openils.Util.readResponse(r)) + var streams_for_printing = []; + while (item_id = openils.Util.readResponse(r)) { + if (self._wants_print_routing[item_id]) { + streams_for_printing.push( + self.item_cache[item_id].stream() + ); + } self.finish_receipt(item_id); + } + if (streams_for_printing.length) + self.print_routing_lists(streams_for_printing); } catch (E) { alert(E); } diff --git a/Open-ILS/xul/staff_client/server/serial/batch_receive_overlay.xul b/Open-ILS/xul/staff_client/server/serial/batch_receive_overlay.xul index adedc30bf7..513038753d 100644 --- a/Open-ILS/xul/staff_client/server/serial/batch_receive_overlay.xul +++ b/Open-ILS/xul/staff_client/server/serial/batch_receive_overlay.xul @@ -108,6 +108,12 @@ &staff.serial.batch_receive.price; + + + &staff.serial.batch_receive.receive; @@ -126,11 +132,12 @@ + - + @@ -144,6 +151,7 @@ + diff --git a/Open-ILS/xul/staff_client/server/skin/serial.css b/Open-ILS/xul/staff_client/server/skin/serial.css index 1c6bfa6d96..2ebfa2b6bf 100644 --- a/Open-ILS/xul/staff_client/server/skin/serial.css +++ b/Open-ILS/xul/staff_client/server/skin/serial.css @@ -20,3 +20,4 @@ checkbox:focus:not([label]) .checkbox-label-box { border: none; } .padded_bottom { padding-bottom: 10px; } +description#print_routing_desc { margin: 0; padding: 0 1em; } -- 2.11.0