[open-ils-commits] r17615 - in trunk/Open-ILS: examples web/css/skin web/css/skin/default web/js/dojo/openils web/js/ui/default web/js/ui/default/serial web/js/ui/default/serial/subscription web/opac/locale/en-US web/templates/default web/templates/default/serial web/templates/default/serial/subscription xul/staff_client/chrome/content/cat xul/staff_client/chrome/locale/en-US xul/staff_client/server/serial (senator)

svn at svn.open-ils.org svn at svn.open-ils.org
Sun Sep 12 15:03:06 EDT 2010


Author: senator
Date: 2010-09-12 15:03:01 -0400 (Sun, 12 Sep 2010)
New Revision: 17615

Added:
   trunk/Open-ILS/web/css/skin/default/serial.css
   trunk/Open-ILS/web/js/ui/default/serial/
   trunk/Open-ILS/web/js/ui/default/serial/list_stream.js
   trunk/Open-ILS/web/js/ui/default/serial/list_subscription.js
   trunk/Open-ILS/web/js/ui/default/serial/subscription.js
   trunk/Open-ILS/web/js/ui/default/serial/subscription/
   trunk/Open-ILS/web/js/ui/default/serial/subscription/caption_and_pattern.js
   trunk/Open-ILS/web/js/ui/default/serial/subscription/issuance.js
   trunk/Open-ILS/web/templates/default/serial/
   trunk/Open-ILS/web/templates/default/serial/list_stream.tt2
   trunk/Open-ILS/web/templates/default/serial/list_subscription.tt2
   trunk/Open-ILS/web/templates/default/serial/subscription.tt2
   trunk/Open-ILS/web/templates/default/serial/subscription/
   trunk/Open-ILS/web/templates/default/serial/subscription/caption_and_pattern.tt2
   trunk/Open-ILS/web/templates/default/serial/subscription/distribution.tt2
   trunk/Open-ILS/web/templates/default/serial/subscription/issuance.tt2
Modified:
   trunk/Open-ILS/examples/fm_IDL.xml
   trunk/Open-ILS/web/css/skin/default.css
   trunk/Open-ILS/web/js/dojo/openils/XUL.js
   trunk/Open-ILS/web/opac/locale/en-US/lang.dtd
   trunk/Open-ILS/xul/staff_client/chrome/content/cat/opac.js
   trunk/Open-ILS/xul/staff_client/chrome/content/cat/opac.xul
   trunk/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties
   trunk/Open-ILS/xul/staff_client/server/serial/batch_receive.js
   trunk/Open-ILS/xul/staff_client/server/serial/pattern_wizard_overlay.xul
Log:
Serials: dojo/autogrid-based scaffolding for building serials objects

Accessible from the staff client OPAC browser's "Actions for this Record" menu
as "Alternate Serial Control", these minimalist interfaces should support a
workflow by which the user can create a subscription and its related parts
(distributions, streams, etc), and get things going in a quick and dirty way
while the existing Serial Control View continues to develop.

Some notable differences in orientation between this and the existing
interface work include:
    - The disuse of call numbers on distributions, instead favoring call number
    application to items by issuance at receive time (i.e., all copies of
    the Sep 2010 issue of Popular Mechanics share a call number rather than
    all copies of Popular Mechanics, any issue, at a given library sharing a
    call number).
    - Lack of attention to binding (although the batch receive interface will
    treat each item as a single bound unit, for barcoding, or will avoid
    creating units altogether if you don't want to barcode your serials).

If this doesn't sound like the way you would do serials, I'd definitely
recommend sticking with Serials Control View and ignoring these interfaces.
Dan Wells' interface work promises broader functionality in the long run.



Modified: trunk/Open-ILS/examples/fm_IDL.xml
===================================================================
--- trunk/Open-ILS/examples/fm_IDL.xml	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/examples/fm_IDL.xml	2010-09-12 19:03:01 UTC (rev 17615)
@@ -3170,12 +3170,24 @@
 			<link field="subscription" reltype="has_a" key="id" map="" class="ssub"/>
 		</links>
 		<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+			<actions>
+				<create permission="ADMIN_SERIAL_CAPTION_PATTERN">
+					<context link="subscription" field="owning_lib" />
+				</create>
+				<retrieve />
+				<update permission="ADMIN_SERIAL_CAPTION_PATTERN">
+					<context link="subscription" field="owning_lib" />
+				</update>
+				<delete permission="ADMIN_SERIAL_CAPTION_PATTERN">
+					<context link="subscription" field="owning_lib" />
+				</delete>
+			</actions>
 		</permacrud>
 	</class>
 
 	<class id="ssub" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="serial::subscription" oils_persist:tablename="serial.subscription" reporter:label="Subscription">
 		<fields oils_persist:primary="id" oils_persist:sequence="serial.subscription_id_seq">
-			<field reporter:label="Id" name="id" reporter:datatype="id"/>
+			<field reporter:label="ID" name="id" reporter:datatype="id"/>
 			<field reporter:label="Owning Library" name="owning_lib" reporter:datatype="org_unit"/>
 			<field reporter:label="Start Date" name="start_date" reporter:datatype="timestamp"/>
 			<field reporter:label="End Date" name="end_date" reporter:datatype="timestamp"/>
@@ -3197,7 +3209,7 @@
 		<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
 			<actions>
 				<create permission="ADMIN_SERIAL_SUBSCRIPTION" context_field="owning_lib"/>
-				<retrieve permission="VIEW_SERIAL_SUBSCRIPTION" context_field="owning_lib"/>
+				<retrieve />
 				<update permission="ADMIN_SERIAL_SUBSCRIPTION" context_field="owning_lib"/>
 				<delete permission="ADMIN_SERIAL_SUBSCRIPTION" context_field="owning_lib"/>
 			</actions>
@@ -3227,7 +3239,7 @@
 			<field reporter:label="ID" name="id" reporter:datatype="id"/>
 			<field reporter:label="Legacy Record Entry" name="record_entry" reporter:datatype="link"/>
 			<field reporter:label="Subscription" name="subscription" reporter:datatype="link"/>
-			<field reporter:label="Holding Lib" name="holding_lib" reporter:datatype="link"/>
+			<field reporter:label="Holding Lib" name="holding_lib" reporter:datatype="org_unit"/>
 			<field reporter:label="Label" name="label" reporter:datatype="text"/>
 			<field reporter:label="Receive Call Number" name="receive_call_number" reporter:datatype="link"/>
 			<field reporter:label="Receive Unit Template" name="receive_unit_template" reporter:datatype="link"/>
@@ -3257,10 +3269,10 @@
 		</links>
 		<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
 			<actions>
-				<create/>
-				<retrieve/>
-				<update/>
-				<delete/>
+				<create permission="ADMIN_SERIAL_DISTRIBUTION" context_field="holding_lib" />
+				<retrieve />
+				<update permission="ADMIN_SERIAL_DISTRIBUTION" context_field="holding_lib" />
+				<delete permission="ADMIN_SERIAL_DISTRIBUTION" context_field="holding_lib" />
 			</actions>
 		</permacrud>
 	</class>
@@ -3299,6 +3311,18 @@
 			<link field="distribution" reltype="has_a" key="id" map="" class="sdist"/>
 		</links>
 		<permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+			<actions>
+				<create permission="ADMIN_SERIAL_STREAM">
+					<context link="distribution" field="holding_lib" />
+				</create>
+				<retrieve />
+				<update permission="ADMIN_SERIAL_STREAM">
+					<context link="distribution" field="holding_lib" />
+				</update>
+				<delete permission="ADMIN_SERIAL_STREAM">
+					<context link="distribution" field="holding_lib" />
+				</delete>
+			</actions>
 		</permacrud>
 	</class>
 

Added: trunk/Open-ILS/web/css/skin/default/serial.css
===================================================================
--- trunk/Open-ILS/web/css/skin/default/serial.css	                        (rev 0)
+++ trunk/Open-ILS/web/css/skin/default/serial.css	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,23 @@
+.oils-serial-header { margin-bottom: 20px; }
+.oils-serial-tab-container { height: 600px; }
+.lesser { margin-top: 2px !important }
+.lesser div:first-child { font-size: 110% !important; }
+.lesser div:last-child { margin-right: 16px; }
+#scap_editor th {
+    font-weight: bold;
+    background-color: #ccc;
+    padding: 2px 8px;
+}
+#scap_editor td { padding: 2px 8px; }
+#scap_editor tr[changed="true"] td { background-color: #fc9; }
+#scap_editor [name="remover"] button { color: red; font-weight: bold; }
+#scap_editor tfoot td { text-align: center; padding-top: 24px; }
+#scap_editor td[name] { text-align: center; }
+.serial-dialog-table tr > * { padding-bottom: 1em; }
+.serial-dialog-table th { text-align: left; padding-right: 1em; }
+.serial-dialog-table tr:last-child td { text-align: center; }
+.serial-additional-controls {
+    text-align: right;
+    margin-right: 16px;
+    padding: 8px 0;
+}

Modified: trunk/Open-ILS/web/css/skin/default.css
===================================================================
--- trunk/Open-ILS/web/css/skin/default.css	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/web/css/skin/default.css	2010-09-12 19:03:01 UTC (rev 17615)
@@ -1,6 +1,7 @@
 /* import the default css for the install applications */
 @import "default/acq.css";
 @import "default/admin.css";
+ at import "default/serial.css";
 /* import the dojo CSS */
 @import "/js/dojo/dojo/resources/dojo.css";
 @import "/js/dojo/dijit/themes/tundra/tundra.css";

Modified: trunk/Open-ILS/web/js/dojo/openils/XUL.js
===================================================================
--- trunk/Open-ILS/web/js/dojo/openils/XUL.js	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/web/js/dojo/openils/XUL.js	2010-09-12 19:03:01 UTC (rev 17615)
@@ -33,6 +33,27 @@
         xulG.new_tab(path, tabInfo, options);
     }
 
+    openils.XUL.newTabEasy = function(url, tab_name, extra_content_params) {
+        var content_params = {
+            "session": openils.User.authtoken,
+            "authtime": openils.User.authtime
+        };
+
+        ["url_prefix", "new_tab", "set_tab", "close_tab", "new_patron_tab",
+            "set_patron_tab", "volume_item_creator", "get_new_session",
+            "holdings_maintenance_tab", "set_tab_name", "open_chrome_window",
+            "url_prefix", "network_meter", "page_meter", "set_statusbar",
+            "set_help_context"
+        ].forEach(function(k) { content_params[k] = xulG[k]; });
+
+        if (extra_content_params)
+            dojo.mixin(content_params, extra_content_params);
+
+        xulG.new_tab(
+            xulG.url_prefix(url), {"tab_name": tab_name}, content_params
+        );
+    };
+
     /**
      * @return bool True if a new session was successfully created, false otherwise.
      */

Added: trunk/Open-ILS/web/js/ui/default/serial/list_stream.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/serial/list_stream.js	                        (rev 0)
+++ trunk/Open-ILS/web/js/ui/default/serial/list_stream.js	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,72 @@
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.NumberSpinner");
+dojo.require("dijit.form.TextBox");
+dojo.require("openils.widget.AutoGrid");
+dojo.require("openils.widget.ProgressDialog");
+dojo.require("openils.PermaCrud");
+
+var pcrud;
+
+function format_routing_label(routing_label) {
+    return routing_label ? routing_label : "[None]";
+}
+
+function load_sstr_grid() {
+    sstr_grid.overrideEditWidgets.distribution =
+        new dijit.form.TextBox({"disabled": true, "value": dist_id});
+
+    sstr_grid.resetStore();
+    sstr_grid.loadAll(
+        {"order_by": {"ssub": "start_date DESC"}},
+        {"distribution": dist_id}
+    );
+}
+
+function load_sdist_display() {
+    pcrud.retrieve(
+        "sdist", dist_id, {
+            "onresponse": function(r) {
+                if (r = openils.Util.readResponse(r)) {
+                    dojo.byId("sdist_label_here").innerHTML = r.label();
+                    load_sdist_org_unit_display(r);
+                }
+            }
+        }
+    );
+}
+
+function load_sdist_org_unit_display(dist) {
+    dojo.byId("sdist_org_unit_name_here").innerHTML =
+        aou.findOrgUnit(dist.holding_lib()).name();
+}
+
+function create_many_streams(fields) {
+    var streams = [];
+    for (var i = 0; i < fields.quantity; i++) {
+        var stream = new sstr();
+        stream.distribution(dist_id);
+        streams.push(stream);
+    }
+
+    progress_dialog.show(true);
+    this.pcrud.create(
+        streams, {
+            "oncomplete": function(r, list) {
+                progress_dialog.hide();
+                sstr_grid.refresh();
+            },
+            "onerror": function(r) {
+                progress_dialog.hide();
+                alert("Error creating streams!"); /* XXX i18n */
+            }
+        }
+    );
+}
+
+openils.Util.addOnLoad(
+    function() {
+        pcrud = new openils.PermaCrud();
+        load_sdist_display();
+        load_sstr_grid();
+    }
+);

Added: trunk/Open-ILS/web/js/ui/default/serial/list_subscription.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/serial/list_subscription.js	                        (rev 0)
+++ trunk/Open-ILS/web/js/ui/default/serial/list_subscription.js	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,46 @@
+dojo.require("dijit.form.Button");
+dojo.require("openils.widget.AutoGrid");
+dojo.require("openils.widget.OrgUnitFilteringSelect");
+dojo.require("openils.BibTemplate");
+
+function format_ssub_link(id) {
+    return "<a href='" + oilsBasePath + "/serial/subscription/" +
+        id + "'>" + id + "</a>";
+}
+
+function load_ssub_grid() {
+    ssub_grid.resetStore();
+    ssub_grid.loadAll({"order_by": {"ssub": "start_date DESC"}}, terms);
+}
+
+openils.Util.addOnLoad(
+    function() {
+        if (terms.record_entry)
+            new openils.BibTemplate({"record": terms.record_entry}).render();
+
+        /* This should be present even if terms.record_entry is undef */
+        ssub_grid.overrideEditWidgets.record_entry = new dijit.form.TextBox(
+            {"value": terms.record_entry, "disabled": true}
+        );
+
+        new openils.User().buildPermOrgSelector(
+            "ADMIN_SERIAL_SUBSCRIPTION",
+            ssub_owner_select,
+            null,
+            function() {
+                dojo.connect(
+                    ssub_owner_select,
+                    "onChange",
+                    function() {
+                        terms.owning_lib = aou.orgNodeTrail(
+                            aou.findOrgUnit(this.attr("value")),
+                            true /* asId */
+                        );
+                        load_ssub_grid();
+                    }
+                );
+                load_ssub_grid();
+            }
+        );
+    }
+);

Added: trunk/Open-ILS/web/js/ui/default/serial/subscription/caption_and_pattern.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/serial/subscription/caption_and_pattern.js	                        (rev 0)
+++ trunk/Open-ILS/web/js/ui/default/serial/subscription/caption_and_pattern.js	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,209 @@
+function SCAPRow() {
+    var self = this;
+    var _fields = ["id", "type", "pattern_code", "active", "create_date"];
+
+    this.init = function(id, manager, datum) {
+        this.id = id;
+        this.manager = manager;
+        this.element = dojo.clone(manager.template);
+
+        /* find the controls for each field */
+        this.controls = {};
+        _fields.forEach(
+            function(k) {
+                self.controls[k] = dojo.query(
+                    "[name='" + k + "'] [control]", self.element
+                )[0];
+            }
+        );
+
+        /* set up the remover button */
+        this.remover = dojo.query("[name='remover'] button", this.element)[0];
+        this.remover.onclick = function() { manager.remove_row(self); };
+
+        this.save_button = dojo.query("[name='save'] button", this.element)[0];
+        this.save_button.onclick = function() { manager.save_row(self); };
+
+        this.wizard_button = dojo.query(
+            "[name='pattern_code'] button", this.element
+        )[0];
+        this.wizard_button.onclick = function() {
+            try {
+                netscape.security.PrivilegeManager.enablePrivilege(
+                    "UniversalXPConnect"
+                );
+                window.openDialog(
+                    xulG.url_prefix("/xul/server/serial/pattern_wizard.xul"),
+                    "pattern_wizard",
+                    "scrollbars=yes", /* XXX doesn't work this way? */
+                    function(value) {
+                        self.controls.pattern_code.value = value;
+                        self.controls.pattern_code.onchange();
+                    }
+                );
+            } catch (E) {
+                alert(E); /* XXX */
+            }
+        };
+
+        /* set up onchange handlers for control fields */
+        this.controls.type.onchange = function() {
+            self.has_changed(true);
+            self.datum.type(this.getValue());
+        };
+        this.controls.pattern_code.onchange = function() {
+            self.has_changed(true);
+            self.datum.pattern_code(this.value);
+        };
+        this.controls.active.onchange = function() {
+            self.has_changed(true);
+            self.datum.active(this.checked ? "t" : "f");
+        };
+
+        this.load_fm_object(datum);
+    };
+
+    this.load_fm_object = function(datum) {
+        if (typeof datum != "undefined") {
+            this.datum = datum;
+
+            this.controls.type.setValue(datum.type());
+            this.controls.pattern_code.value = datum.pattern_code();
+            this.controls.active.checked = openils.Util.isTrue(datum.active());
+            this.controls.id.innerHTML = datum.id() || "";
+            this.controls.create_date.innerHTML =
+                openils.Util.timeStamp(datum.create_date());
+
+            this.has_changed(false);
+        } else {
+            this.datum = new scap();
+            this.datum.subscription(this.manager.sub_id);
+
+            _fields.forEach(
+                function(k) {
+                    try { self.controls[k].onchange(); } catch (E) { ; }
+                }
+            );
+        }
+    };
+
+    this.has_changed = function(has) {
+        if (typeof has != "undefined") {
+            this._has_changed = has;
+            this.save_button.disabled = !has;
+            dojo.attr(this.element, "changed", String(has));
+        }
+
+        return this._has_changed;
+    };
+
+    this.init.apply(this, arguments);
+}
+
+function SCAPEditor() {
+    var self = this;
+
+    this.init = function(sub_id, pcrud) {
+        this.sub_id = sub_id;
+        this.pcrud = pcrud || new openils.PermaCrud();
+
+        this.setup();
+        this.reset();
+        this.load_existing();
+    };
+
+    this.reset = function() {
+        this.virtRowCount = 0;
+        this.rows = {};
+
+        dojo.empty(this.body);
+    };
+
+    this.setup = function() {
+        var template = dojo.query("#scap_editor tbody tr")[0];
+        this.body = template.parentNode;
+        this.template = this.body.removeChild(template);
+
+        dojo.query("#scap_editor button[name='add']")[0].onclick =
+            function() { self.add_row(); };
+
+        openils.Util.show("scap_editor");
+    };
+
+    this.load_existing = function() {
+        this.pcrud.search("scap", {
+                "subscription": this.sub_id
+            }, {
+                "order_by": {"scap": "create_date"},
+                "onresponse": function(r) {
+                    if (r = openils.Util.readResponse(r)) {
+                        r.forEach(function(datum) { self.add_row(datum); });
+                    }
+                }
+            }
+        );
+    };
+
+    this.add_row = function(datum) {
+        var id;
+        if (typeof datum == "undefined") {
+            id = --(this.virtRowCount);
+            this.rows[id] = new SCAPRow(id, this);
+        } else {
+            id = datum.id();
+            this.rows[id] = new SCAPRow(id, this, datum);
+        }
+
+        dojo.place(this.rows[id].element, this.body, "last");
+    };
+
+    this.save_row = function(row) {
+        var old_id = row.id;
+        if (old_id < 0) {
+            this.pcrud.create(
+                row.datum, {
+                    "oncomplete": function(r, list) {
+                        openils.Util.readResponse(r);
+                        var new_id = list[0].id();
+                        row.id = new_id;
+                        delete self.rows[old_id];
+                        self.rows[new_id] = row;
+                        row.load_fm_object(list[0]);
+                        row.has_changed(false);
+                    }
+                }
+            );
+        } else {
+            this.pcrud.update(
+                row.datum, {
+                    "oncomplete": function(r, list) {
+                        openils.Util.readResponse(r);
+                        row.has_changed(false);
+                    }
+                }
+            );
+        }
+    };
+
+    this.remove_row = function(row) {
+        function _remove(row) {
+            dojo.destroy(self.rows[row.id].element);
+            delete self.rows[row.id];
+        }
+
+        if (row.id < 0) { /* virtual row */
+            _remove(row);
+        } else { /* real row */
+            this.pcrud.eliminate(
+                row.datum, {
+                    "oncomplete": function(r, list) {
+                        openils.Util.readResponse(r);
+                        _remove(row);
+                    }
+                }
+            );
+        }
+    };
+
+    this.init.apply(this, arguments);
+}

Added: trunk/Open-ILS/web/js/ui/default/serial/subscription/issuance.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/serial/subscription/issuance.js	                        (rev 0)
+++ trunk/Open-ILS/web/js/ui/default/serial/subscription/issuance.js	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,76 @@
+function fresh_scap_selector(grid) {
+    pcrud.search(
+        "scap", {"subscription": sub_id, "active": "t"}, {
+            "oncomplete": function(r) {
+                var data = scap.toStoreData(openils.Util.readResponse(r));
+                var selector = new dijit.form.FilteringSelect(
+                    {
+                        "store": new dojo.data.ItemFileReadStore({"data":data}),
+                        "searchAttr": "id"
+                    },
+                    dojo.create("span")
+                );
+                selector.shove = {
+                    "create": data.items.length ? data.items[0].id : ""
+                };
+                dojo.connect(
+                    selector, "onChange", null, function() {
+                        if (this.item) {
+                            var widget =
+                                iss_grid.overrideEditWidgets.holding_type;
+                            widget.attr("value", this.item.type);
+                            widget.attr("disabled", true);
+                        }
+                    }
+                );
+
+                grid.overrideEditWidgets.caption_and_pattern = selector;
+            }
+        }
+    );
+}
+
+function prepare_prediction_dialog() {
+    if (sub.end_date()) {
+        prediction_dialog_end_date.attr("disabled", false);
+        prediction_dialog_end_date.attr("checked", true);
+    } else {
+        prediction_dialog_end_num.attr("checked", true);
+        prediction_dialog_end_date.attr("disabled", true);
+        prediction_dialog_num_to_predict.focus();
+    }
+    prediction_dialog_submit.attr("disabled", false);
+}
+
+function generate_predictions(fields) {
+    var args = {"ssub_id": sub.id(), "all_dists": true};
+
+    if (fields.end_how == "date") {
+        args.end_date = sub.end_date();
+    } else if ((num = Number(fields.num_to_predict)) > 0)  {
+        args.num_to_predict = num;
+    } else {
+        alert("Go with a whole, positive number."); /* XXX i18n */
+        return;
+    }
+
+    progress_dialog.show(true);
+    try {
+        fieldmapper.standardRequest(
+            ["open-ils.serial", "open-ils.serial.make_predictions"], {
+                "params": [openils.User.authtoken, args],
+                "async": true,
+                "onresponse": function(r) {
+                    openils.Util.readResponse(r); /* tests for events */
+                },
+                "oncomplete": function() {
+                    progress_dialog.hide();
+                    iss_grid.refresh();
+                }
+            }
+        );
+    } catch (E) {
+        alert(E);
+        progess_dialog.hide();
+    }
+}

Added: trunk/Open-ILS/web/js/ui/default/serial/subscription.js
===================================================================
--- trunk/Open-ILS/web/js/ui/default/serial/subscription.js	                        (rev 0)
+++ trunk/Open-ILS/web/js/ui/default/serial/subscription.js	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,152 @@
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.RadioButton");
+dojo.require("dijit.form.FilteringSelect");
+dojo.require("dijit.form.DropDownButton");
+dojo.require("dijit.TooltipDialog");
+dojo.require("dijit.layout.TabContainer");
+dojo.require("dijit.layout.ContentPane");
+dojo.require("dojox.grid.DataGrid");
+dojo.require("openils.widget.AutoGrid");
+dojo.require("openils.widget.ProgressDialog");
+dojo.require("openils.PermaCrud");
+
+var pcrud;
+var sub;
+
+/* typing save: add {get,set}Value() to all HTML <select> elements */
+HTMLSelectElement.prototype.getValue = function() {
+    return this.options[this.selectedIndex].value;
+}
+HTMLSelectElement.prototype.setValue = function(s) {
+    for (var i = 0; i < this.options.length; i++) {
+        if (s == this.options[i].value) {
+            this.selectedIndex = i;
+            break;
+        }
+    }
+}
+
+function load_sub_grid(id) {
+    if (!pcrud) return; /* first run, onLoad hasn't fired yet */
+    if (!sub_grid._fresh) {
+        pcrud.retrieve(
+            "ssub", id, {
+                "onresponse": function(r) {
+                    if (r = openils.Util.readResponse(r)) {
+                        sub = r;
+                        sub_grid.setStore(
+                            new dojo.data.ItemFileReadStore(
+                                {"data": ssub.toStoreData([r])}
+                            )
+                        );
+                        sub_grid._fresh = true;
+                    }
+                }
+            }
+        );
+    }
+}
+
+/* TODO: make these formatters caching */
+function format_bib(bib_id) {
+    if (!bib_id) {
+        return "";
+    } else {
+        var result;
+        fieldmapper.standardRequest(
+            ["open-ils.search",
+                "open-ils.search.biblio.record.mods_slim.retrieve"], {
+                "async": false,
+                "params": [bib_id],
+                "oncomplete": function(r) {
+                    if (r = openils.Util.readResponse(r)) {
+                        var parts = [];
+                        if (r.title())
+                            parts.push(r.title());
+                        if (r.author())
+                            parts.push(r.author());
+                        if (r.author())
+                            parts.push(r.publisher());
+
+                        if (!parts.length)
+                            parts.push(r.tcn());
+
+                        result = parts.join(" / ");
+                    }
+                }
+            }
+        );
+        return "<a href='" + oilsBasePath + "/serial/list_subscription/" +
+            bib_id + "'>" + result + "</a>";
+    }
+}
+
+function format_date(s) {
+    return s ? openils.Util.timeStamp(s, {"selector": "date"}) : "";
+}
+
+function format_org_unit(aou_id) {
+    return aou_id ? aou.findOrgUnit(aou_id).shortname() : "";
+}
+
+function get_sdist(rowIndex, item) {
+    if (!item) return {"id": "", "label": ""};
+    return {
+        "id": this.grid.store.getValue(item, "id"),
+        "label": this.grid.store.getValue(item, "label")
+    };
+}
+
+function format_sdist_label(blob) {
+    if (!blob.id) return "";
+    var link = "<a href='" +
+        oilsBasePath + "/serial/list_stream/" + blob.id +
+        "'>" + (blob.label ? blob.label : "[None]") + "</a>" + /* XXX i18n */
+        "<span id='dist_link_" + blob.id + "'></span>";
+
+    /* XXX kludgy kludge kludge */
+    setTimeout(function() { append_stream_count(blob.id); }, 200);
+
+    return link;
+}
+
+function append_stream_count(dist_id) {
+    var span = dojo.byId("dist_link_" + dist_id);
+    if (span.childNodes.length) /* textNodes count as childnodes */
+        return;
+    pcrud.search(
+        "sstr", {"distribution": dist_id}, {
+            "id_list": true,
+            "oncomplete": function(r) {
+                var resp = openils.Util.readResponse(r);
+                var count = resp ? resp.length : 0;
+
+                /* XXX i18n */
+                span.innerHTML = "&nbsp;&nbsp; " + count + " stream(s)";
+            }
+        }
+    );
+}
+
+function open_batch_receive() {
+    if (!sub) {
+        alert("Let the interface load all the way first.");
+        return;
+    }
+
+    var url = "/xul/server/serial/batch_receive.xul?docid=" +
+        sub.record_entry() + "&subid=" + sub.id();
+
+    try {
+        openils.XUL.newTabEasy(url, "Batch Receive"); /* XXX i18n */
+    } catch (E) {
+        location.href = url;
+    }
+}
+
+openils.Util.addOnLoad(
+    function() {
+        pcrud = new openils.PermaCrud();
+        load_sub_grid(sub_id);
+    }
+);

Modified: trunk/Open-ILS/web/opac/locale/en-US/lang.dtd
===================================================================
--- trunk/Open-ILS/web/opac/locale/en-US/lang.dtd	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/web/opac/locale/en-US/lang.dtd	2010-09-12 19:03:01 UTC (rev 17615)
@@ -316,6 +316,8 @@
 <!ENTITY staff.cat.opac.view_holds.label "View Holds">
 <!ENTITY staff.cat.opac.view_orders.accesskey "r">
 <!ENTITY staff.cat.opac.view_orders.label "View/Place Orders">
+<!ENTITY staff.cat.opac.alt_serial.accesskey "a">
+<!ENTITY staff.cat.opac.alt_serial.label "Alternate Serial Control">
 <!ENTITY staff.cat.opac.batch_receive.accesskey "i">
 <!ENTITY staff.cat.opac.batch_receive.label "Serials Batch Receive">
 <!ENTITY staff.cat.popup.add_to_bucket "Add to Bucket">

Added: trunk/Open-ILS/web/templates/default/serial/list_stream.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/serial/list_stream.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/serial/list_stream.tt2	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,73 @@
+[% WRAPPER default/base.tt2 %]
+[% ctx.page_title = "Streams" %]
+<script
+    type="text/javascript"
+    src="[% ctx.media_prefix %]/js/ui/default/serial/list_stream.js">
+</script>
+<script type="text/javascript">
+    var dist_id = "[% ctx.page_args.0 %]";
+</script>
+<div dojoType="dijit.layout.ContentPane" layoutAlign="client">
+    <div dojoType="dijit.layout.ContentPane"
+        layoutAlign="top" class="oils-header-panel">
+        <div>Streams</div>
+        <div>
+            <button dojoType="dijit.form.Button"
+                onClick="sstr_grid.showCreateDialog()">New Stream</button>
+            <button dojoType="dijit.form.Button"
+                onClick="multi_stream_dialog.show()">
+                Create Many Streams
+            </button>
+            <button dojoType="dijit.form.Button"
+                onClick="sstr_grid.refresh()">Refresh Grid</button>
+            <button dojoType="dijit.form.Button"
+                onClick="sstr_grid.deleteSelected()">Delete Selected</button>
+        </div>
+    </div>
+    <div>
+        Showing streams attached to the distribution,
+        <em id="sdist_label_here"></em>
+        (<span id="sdist_org_unit_name_here"></span>).
+    </div>
+    <table jsId="sstr_grid"
+        dojoType="openils.widget.AutoGrid"
+        query="{id: '*'}"
+        suppressFields="['distribution']"
+        fmClass="sstr"
+        defaultCellWidth="'auto'"
+        showPaginator="true"
+        editOnEnter="true">
+        <thead>
+            <tr>
+                <th field="routing_label" formatter="format_routing_label">
+                </th>
+            </tr>
+        </thead>
+    </table>
+</div>
+<div class="hidden">
+    <div dojoType="dijit.Dialog"
+        execute="create_many_streams(arguments[0]);"
+        title="Create Streams"
+        jsId="multi_stream_dialog">
+        <table class="serial-dialog-table">
+            <tr>
+                <th>How many?</th>
+                <td>
+                    <input dojoType="dijit.form.NumberSpinner"
+                        value="1" smallDelta="1" name="quantity"
+                        constraints="{'min': 1, 'max': 1000}" />
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <button dojoType="dijit.form.Button" type="submit">
+                        Create
+                    </button>
+                </td>
+            </tr>
+        </table>
+    </div>
+    <div dojoType="openils.widget.ProgressDialog" jsId="progress_dialog"></div>
+</div>
+[% END %]

Added: trunk/Open-ILS/web/templates/default/serial/list_subscription.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/serial/list_subscription.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/serial/list_subscription.tt2	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,59 @@
+[% WRAPPER default/base.tt2 %]
+[% ctx.page_title = "Subscriptions" %]
+<script
+    type="text/javascript"
+    src="[% ctx.media_prefix %]/js/ui/default/serial/list_subscription.js">
+</script>
+<script type="text/javascript">
+    var terms = {
+        "owning_lib": aou.orgNodeTrail(
+            aou.findOrgUnit(openils.User.user.ws_ou()),
+            true /* asId */
+        )
+    };
+
+    if (docid = "[% ctx.page_args.0 %]") /* assignment intentional */
+        terms.record_entry = docid;
+</script>
+<div dojoType="dijit.layout.ContentPane" layoutAlign="client">
+    <div dojoType="dijit.layout.ContentPane"
+        layoutAlign="top" class="oils-header-panel">
+        <div>Subscriptions</div>
+        <div>
+            <button
+                dojoType="dijit.form.Button"
+                onClick="ssub_grid.showCreateDialog()">New Subscription</button>
+            <button
+                dojoType="dijit.form.Button"
+                onClick="ssub_grid.deleteSelected()">Delete Selected</button>
+        </div>
+    </div>
+    <div>
+        <span>
+            Show subscriptions related to
+            <em type="opac/slot-data" datatype="marcxml"
+                query="datafield[tag=245]" limit="1"></em>
+            owned at or above:
+        </span>
+        <select dojoType="openils.widget.OrgUnitFilteringSelect"
+            jsId="ssub_owner_select"
+            searchAttr="shortname" labelAttr="shortname">
+        </select>
+    </div>
+    <table jsId="ssub_grid"
+        dojoType="openils.widget.AutoGrid"
+        query="{id: '*'}"
+        fieldOrder="['id','owning_lib','start_date','end_date']"
+        suppressFields="['record_entry']"
+        fmClass="ssub"
+        showPaginator="true"
+        showSequenceFields="true"
+        editOnEnter="true">
+        <thead>
+            <tr>
+                <th field="id" formatter="format_ssub_link"></th>
+            </tr>
+        </thead>
+    </table>
+</div>
+[% END %]

Added: trunk/Open-ILS/web/templates/default/serial/subscription/caption_and_pattern.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/serial/subscription/caption_and_pattern.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/serial/subscription/caption_and_pattern.tt2	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,52 @@
+<div dojoType="dijit.layout.ContentPane" layout="top">
+    <table id="scap_editor" class="hidden">
+        <thead>
+            <tr>
+                <th>ID</th>
+                <th>Type</th>
+                <th>Pattern Code</th>
+                <th>Create Date</th>
+                <th>Active</th>
+                <th>Remove</th>
+                <th>Save Changes</th>
+            </tr>
+        </thead>
+        <tbody>
+            <tr>
+                <td name="id">
+                    <span control="true"></span>
+                </td>
+                <td name="type">
+                    <select control="true">
+                        <option value="basic">(853) Basic</option>
+                        <option value="supplement">(854) Supplement</option>
+                        <option value="index">(855) Index</option>
+                    </select>
+                </td>
+                <td name="pattern_code">
+                    <input type="text" size="16" control="true" />
+                    <button>Wizard ...</button>
+                </td>
+                <td name="create_date">
+                    <span control="true"></span>
+                </td>
+                <td name="active">
+                    <input type="checkbox" control="true" />
+                </td>
+                <td name="remover">
+                    <button>X</button>
+                </td>
+                <td name="save">
+                    <button>Save Changes</button>
+                </td>
+            </tr>
+        </tbody>
+        <tfoot>
+            <tr>
+                <td colspan="7">
+                    <button name="add">Add Caption and Pattern</button>
+                </td>
+            </tr>
+        </tfoot>
+    </table>
+</div>

Added: trunk/Open-ILS/web/templates/default/serial/subscription/distribution.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/serial/subscription/distribution.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/serial/subscription/distribution.tt2	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,33 @@
+<div dojoType="dijit.layout.ContentPane" layout="top"
+    class="oils-header-panel lesser">
+    <div>Distributions</div>
+    <div style="margin-right: 16px;">
+        <span dojoType="dijit.form.Button"
+            onClick="dist_grid.refresh();">Refresh Grid</span>
+        <span dojoType="dijit.form.Button"
+            onClick="dist_grid.showCreateDialog();">New Distribution</span>
+        <span dojoType="dijit.form.Button"
+            onClick="dist_grid.deleteSelected();">Delete Selected</span>
+    </div>
+</div>
+<div dojoType="dijit.layout.ContentPane" layout="top">
+    <table
+        jsId="dist_grid"
+        dojoType="openils.widget.AutoGrid"
+        autoHeight="true"
+        fieldOrder="['subscription','label','holding_lib']"
+        suppressFields="['record_entry','subscription','receive_call_number','bind_call_number','bind_unit_template']"
+        suppressEditFields="['record_entry','receive_call_number','bind_call_number','bind_unit_template']"
+        defaultCellWidth="'auto'"
+        fmClass="sdist"
+        query="{id: '*'}"
+        editOnEnter="true"
+        showPaginator="true">
+        <thead>
+            <tr>
+                <th field="label"
+                    get="get_sdist" formatter="format_sdist_label"></th>
+            </tr>
+        </thead>
+    </table>
+</div>

Added: trunk/Open-ILS/web/templates/default/serial/subscription/issuance.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/serial/subscription/issuance.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/serial/subscription/issuance.tt2	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,78 @@
+<div dojoType="dijit.layout.ContentPane" layout="top"
+    class="oils-header-panel lesser">
+    <div>Issuances</div>
+    <div style="margin-right: 16px;">
+        <span dojoType="dijit.form.Button"
+            onclick="iss_grid.refresh();">Refresh Grid</span>
+        <span dojoType="dijit.form.Button"
+            onclick="iss_grid.showCreateDialog();">New Issuance</span>
+        <span dojoType="dijit.form.Button"
+            onclick="iss_grid.deleteSelected();">Delete Selected</span>
+    </div>
+</div>
+<div class="serial-additional-controls">
+    <span dojoType="dijit.form.Button"
+        onclick="prediction_dialog.show();">Generate Predictions</span>
+</div>
+<div dojoType="dijit.layout.ContentPane" layout="top">
+    <table jsId="iss_grid"
+        dojoType="openils.widget.AutoGrid"
+        autoHeight="true"
+        fieldOrder="['subscription','creator','editor','label','date_published','caption_and_pattern','holding_type']"
+        suppressFields="['subscription','holding_link_id','create_date','edit_date','creator','editor']"
+        suppressEditFields="['id','holding_link_id','create_date','edit_date']"
+        defaultCellWidth="'auto'"
+        fmClass="siss"
+        query="{id: '*'}"
+        editOnEnter="true"
+        showPaginator="true">
+    </table>
+</div>
+<div class="hidden">
+    <div dojoType="dijit.Dialog"
+        title="Generate Issuance and Item Predictions"
+        execute="generate_predictions(arguments[0]);"
+        jsId="prediction_dialog">
+        <script type="dojo/connect" event="onShow">
+            prepare_prediction_dialog();
+        </script>
+        <table class="serial-dialog-table">
+            <tr>
+                <th>
+                    <input dojoType="dijit.form.RadioButton"
+                        id="end_date" name="end_how" value="date"
+                        checked="false" disabled="true"
+                        jsId="prediction_dialog_end_date" />
+                    <label for="end_date">
+                        Predict until end of subscription
+                    </label>
+                </th>
+                <td></td>
+            </tr>
+            <tr>
+                <th>
+                    <input dojoType="dijit.form.RadioButton"
+                        id="end_num" name="end_how" value="number"
+                        checked="true" jsId="prediction_dialog_end_num"
+                        onChange="if (this.attr('checked')) setTimeout(function(){prediction_dialog_num_to_predict.focus();},200);" />
+                    <label for="end_num">
+                        Predict a certain number of issuances:
+                    </label>
+                </th>
+                <td>
+                    <input dojoType="dijit.form.TextBox"
+                        style="width: 5em;"
+                        jsId="prediction_dialog_num_to_predict"
+                        name="num_to_predict" />
+                </td>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <button dojoType="dijit.form.Button"
+                        jsId="prediction_dialog_submit"
+                        type="submit" disabled="true">Generate</button>
+                </td>
+            </tr>
+        </table>
+    </div>
+</div>

Added: trunk/Open-ILS/web/templates/default/serial/subscription.tt2
===================================================================
--- trunk/Open-ILS/web/templates/default/serial/subscription.tt2	                        (rev 0)
+++ trunk/Open-ILS/web/templates/default/serial/subscription.tt2	2010-09-12 19:03:01 UTC (rev 17615)
@@ -0,0 +1,130 @@
+[% WRAPPER "default/base.tt2" %]
+<script>
+    var cap_editor;
+    var sub_id = "[% ctx.page_args.0 %]";
+</script>
+<script src="[% ctx.media_prefix %]/js/ui/default/serial/subscription.js">
+</script>
+<script src="[% ctx.media_prefix %]/js/ui/default/serial/subscription/caption_and_pattern.js">
+</script>
+<script src="[% ctx.media_prefix %]/js/ui/default/serial/subscription/issuance.js">
+</script>
+
+<div dojoType="dijit.layout.ContentPane" layout="top" class="oils-header-panel">
+    <div>Subscription Details</div>
+    <div>
+        <span dojoType="dijit.form.Button" onClick="open_batch_receive();">
+            Batch Item Receive
+        </span>
+    </div>
+</div>
+
+<div dojoType="dijit.layout.TabContainer" class="oils-serial-tab-container">
+
+    <!-- Subscription Summary -->
+    <div dojoType="dijit.layout.ContentPane" title="Summary" selected="true">
+        <script type="dojo/connect" event="onShow">
+            load_sub_grid(sub_id);
+        </script>
+        <table jsId="sub_grid"
+            dojoType="dojox.grid.DataGrid" query="{id: '*'}" rowSelector="20px">
+            <thead>
+                <tr>
+                    <th field="id">ID</th>
+                    <th field="owning_lib" formatter="format_org_unit">
+                        Owning Library
+                    </th>
+                    <th field="start_date" formatter="format_date">
+                        Start Date
+                    </th>
+                    <th field="end_date" formatter="format_date">
+                        End Date
+                    </th>
+                    <th field="record_entry" width="20em"
+                        formatter="format_bib">
+                        Bibliographic Record
+                    </th>
+                    <th field="expected_date_offset">Expected Date Offset</th>
+                </tr>
+            </thead>
+        </table>
+    </div>
+
+    <!-- Distributions -->
+    <div dojoType="dijit.layout.ContentPane"
+        title="Distributions" layoutAlign="client">
+        <script type="dojo/connect" event="onShow">
+            if (!dist_grid._fresh) {
+                dist_grid.resetStore();
+                dist_grid.loadAll(
+                    {"order_by": {"sdist": "holding_lib"}},
+                    {"subscription": sub_id}
+                );
+                dist_grid._fresh = true;
+            }
+
+            if (!dist_grid.overrideEditWidgets.subscription) {
+                dist_grid.overrideEditWidgets.subscription =
+                    new dijit.form.TextBox({
+                        "disabled": true, "value": sub_id
+                    });
+            }
+        </script>
+        [% INCLUDE "default/serial/subscription/distribution.tt2" %]
+    </div>
+
+    <!-- Caption/Pattern -->
+    <div dojoType="dijit.layout.ContentPane"
+        title="Captions and Patterns" layoutAlign="client">
+        <script type="dojo/connect" event="onShow">
+            if (!cap_editor) cap_editor = new SCAPEditor(sub_id);
+        </script>
+        [% INCLUDE "default/serial/subscription/caption_and_pattern.tt2" %]
+    </div>
+
+    <!-- Issuances -->
+    <div dojoType="dijit.layout.ContentPane"
+        title="Issuances" layoutAlign="client">
+        <script type="dojo/connect" event="onShow">
+            if (!iss_grid._fresh) {
+                iss_grid.resetStore();
+                iss_grid.loadAll(
+                    {"order_by": {"siss": "date_published"}},
+                    {"subscription": sub_id}
+                );
+                iss_grid._fresh = true;
+            }
+
+            if (!iss_grid.overrideEditWidgets.subscription) {
+                iss_grid.overrideEditWidgets.subscription =
+                    new dijit.form.TextBox({
+                        "disabled": true, "value": sub_id
+                    });
+
+                iss_grid.overrideEditWidgets.creator =
+                    new dijit.form.TextBox({"disabled": true});
+                iss_grid.overrideEditWidgets.creator.shove = {
+                    "create": openils.User.user.id()
+                };
+
+                iss_grid.overrideEditWidgets.editor =
+                    new dijit.form.TextBox({
+                        "disabled": true, "value": openils.User.user.id()
+                    });
+
+                iss_grid.overrideEditWidgets.holding_type =
+                    new dijit.form.TextBox({"disabled": true});
+                iss_grid.overrideEditWidgets.holding_type.shove = {"create":""};
+
+                iss_grid.overrideEditWidgets.holding_type =
+                    new dijit.form.TextBox;
+            }
+            fresh_scap_selector(iss_grid);
+        </script>
+        [% INCLUDE "default/serial/subscription/issuance.tt2" %]
+    </div>
+</div>
+<div class="hidden">
+    <div dojoType="openils.widget.ProgressDialog" jsId="progress_dialog"></div>
+</div>
+[% END %]

Modified: trunk/Open-ILS/xul/staff_client/chrome/content/cat/opac.js
===================================================================
--- trunk/Open-ILS/xul/staff_client/chrome/content/cat/opac.js	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/xul/staff_client/chrome/content/cat/opac.js	2010-09-12 19:03:01 UTC (rev 17615)
@@ -303,6 +303,39 @@
     }
 }
 
+function open_alt_serial_mgmt() {
+    try {
+        var content_params = {
+            "session": ses(),
+            "authtime": ses("authtime"),
+            "show_nav_buttons": true,
+            "no_xulG": false,
+            "show_print_button": false
+        };
+
+        ["url_prefix", "new_tab", "set_tab", "close_tab", "new_patron_tab",
+            "set_patron_tab", "volume_item_creator", "get_new_session",
+            "holdings_maintenance_tab", "set_tab_name", "open_chrome_window",
+            "url_prefix", "network_meter", "page_meter", "set_statusbar",
+            "set_help_context"
+        ].forEach(function(k) { content_params[k] = xulG[k]; });
+
+        var loc = urls.XUL_BROWSER + "?url=" + window.escape(
+            xulG.url_prefix("/eg/serial/list_subscription/") + docid
+        );
+        xulG.new_tab(
+            loc, {
+                "tab_name": $("offlineStrings").getString(
+                    "staff.cat.opac.serial_alt_mgmt"
+                ),
+                "browser": false
+            }, content_params
+        );
+    } catch (E) {
+        g.error.sdump("D_ERROR", E);
+    }
+}
+
 function set_opac() {
     g.view = 'opac';
     try {
@@ -539,28 +572,6 @@
     };
 }
 
-function serials_mgmt_new_tab() {
-    try {
-        /* XXX should the following be put into a function somewhere? the gist
-         * of this setting up of content_params seems to be duplicated all
-         * over the place.
-         */
-        var content_params = {"session": ses(), "authtime": ses("authtime")};
-        ["url_prefix", "new_tab", "set_tab", "close_tab", "new_patron_tab",
-            "set_patron_tab", "volume_item_creator", "get_new_session",
-            "holdings_maintenance_tab", "set_tab_name", "open_chrome_window",
-            "url_prefix", "network_meter", "page_meter", "set_statusbar",
-            "set_help_context"
-        ].forEach(function(k) { content_params[k] = xulG[k]; });
-
-        xulG.new_tab(
-            xulG.url_prefix(urls.XUL_SERIAL_RECORD_ENTRY), {}, content_params
-        );
-    } catch (E) {
-        g.error.sdump('D_ERROR', E);
-    }
-}
-
 function bib_in_new_tab() {
     try {
         var url = browser_frame.contentWindow.g.browser.controller.view.browser_browser.contentWindow.wrappedJSObject.location.href;

Modified: trunk/Open-ILS/xul/staff_client/chrome/content/cat/opac.xul
===================================================================
--- trunk/Open-ILS/xul/staff_client/chrome/content/cat/opac.xul	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/xul/staff_client/chrome/content/cat/opac.xul	2010-09-12 19:03:01 UTC (rev 17615)
@@ -73,7 +73,8 @@
                         <menu id="mfhd_delete" label="&staff.serial.mfhd_menu.delete.label;"/>
                     </menupopup>
                 </menu>
-                <menuitem id="serctrl_view" label="&staff.serial.serctrl_view.label;" oncommand="set_serctrl_view();"/>
+                <menuitem id="serctrl_view" label="&staff.serial.serctrl_view.label;" oncommand="set_serctrl_view();" />
+                <menuitem label="&staff.cat.opac.alt_serial.label;" accesskey="&staff.cat.opac.alt_serial.accesskey;" id="alt_serial" oncommand="open_alt_serial_mgmt();" />
                 <menuitem label="&staff.cat.opac.batch_receive.label;" accesskey="&staff.cat.opac.batch_receive.accesskey;" id="batch_receive" oncommand="batch_receive_in_new_tab();"/>
                 </menupopup>
                 </menu>

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	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties	2010-09-12 19:03:01 UTC (rev 17615)
@@ -261,6 +261,7 @@
 staff.cat.opac.title_for_hold_transfer.success.label=Holds transferred.
 staff.cat.opac.title_for_hold_transfer.failure.label=Holds not transferred.
 staff.cat.opac.related_items=Related Lineitems
+staff.cat.opac.serial_alt_mgmt=Subscriptions
 staff.cat.create_or_rebarcode_items=Create or Re-barcode Items
 printing.nothing_to_reprint=Nothing to re-print
 printing.prompt_for_external_print_cmd=Enter external print command and parameters (use %receipt.txt% or %receipt.html% as the file containing the print data. Those values will be substituted with the proper path.):

Modified: trunk/Open-ILS/xul/staff_client/server/serial/batch_receive.js
===================================================================
--- trunk/Open-ILS/xul/staff_client/server/serial/batch_receive.js	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/xul/staff_client/server/serial/batch_receive.js	2010-09-12 19:03:01 UTC (rev 17615)
@@ -21,7 +21,7 @@
 function BatchReceiver() {
     var self = this;
 
-    this.init = function(authtoken, bib_id) {
+    this.init = function(authtoken, bib_id, sub_id) {
         if (authtoken) {
             this.user = new openils.User({"authtoken": authtoken});
             this.pcrud = new openils.PermaCrud({"authtoken": authtoken});
@@ -73,7 +73,7 @@
         this.item_cache = {};
 
         if (bib_id)
-            this.bib_lookup(bib_id, null, true);
+            this.bib_lookup(bib_id, null, true, sub_id);
 
         busy(false);
     };
@@ -453,7 +453,7 @@
         }
     };
 
-    this.bib_lookup = function(bib_search_term, evt, is_actual_id) {
+    this.bib_lookup = function(bib_search_term, evt, is_actual_id, sub_id) {
         if (evt && evt.keyCode != 13) return;
 
         if (!bib_search_term) {
@@ -497,7 +497,7 @@
                         } else {
                             self.bibdata = list[0];
                             self._show_bibdata_bits();
-                            self.choose_subscription();
+                            self.choose_subscription(sub_id);
                         }
                     } else {
                         alert(S("bib_lookup.not_found"));
@@ -513,7 +513,7 @@
         );
     };
 
-    this.choose_subscription = function() {
+    this.choose_subscription = function(sub_id) {
         hide("batch_receive_bib");
         hide("batch_receive_entry");
         hide("batch_receive_sub_bits");
@@ -521,7 +521,11 @@
 
         var subs = this.bibdata.bre.subscriptions();
 
-        if (subs.length > 1) {
+        if (sub_id) {
+            this.choose_issuance(
+                subs.filter(function(o) { return o.id() == sub_id; })[0]
+            );
+        } else if (subs.length > 1) {
             var menulist = dojo.create("menulist", {"id": "sub_chooser"});
             var menupopup = dojo.create("menupopup", {}, menulist, "only");
 
@@ -912,6 +916,6 @@
     batch_receiver = new BatchReceiver(
         (typeof ses == "function" ? ses() : 0) ||
             cgi.param("ses") || dojo.cookie("ses"),
-        cgi.param("docid") || null
+        cgi.param("docid") || null, cgi.param("subid") || null
     );
 }

Modified: trunk/Open-ILS/xul/staff_client/server/serial/pattern_wizard_overlay.xul
===================================================================
--- trunk/Open-ILS/xul/staff_client/server/serial/pattern_wizard_overlay.xul	2010-09-12 18:43:38 UTC (rev 17614)
+++ trunk/Open-ILS/xul/staff_client/server/serial/pattern_wizard_overlay.xul	2010-09-12 19:03:01 UTC (rev 17615)
@@ -157,8 +157,8 @@
                     label="Use chronology captions?" />
                 <vbox id="chron_editor_here" class="hideme">
                     <description class="step">
-                        Generally, each caption should be a smaller unit of
-                        time than the preceding caption.
+                        Each caption must be a smaller unit of
+                        time than the preceding caption.<!-- XXX TODO enforce -->
                     </description>
                     <grid>
                         <columns>



More information about the open-ils-commits mailing list