Backport r17615 from trunk: serials quick-and-dirty admin interfaces
authorsenator <senator@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Sun, 12 Sep 2010 19:04:48 +0000 (19:04 +0000)
committersenator <senator@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Sun, 12 Sep 2010 19:04:48 +0000 (19:04 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_2_0@17616 dcc99617-32d9-48b4-a31d-7c20da2025e4

21 files changed:
Open-ILS/examples/fm_IDL.xml
Open-ILS/web/css/skin/default.css
Open-ILS/web/css/skin/default/serial.css [new file with mode: 0644]
Open-ILS/web/js/dojo/openils/XUL.js
Open-ILS/web/js/ui/default/serial/list_stream.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/serial/list_subscription.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/serial/subscription.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/serial/subscription/caption_and_pattern.js [new file with mode: 0644]
Open-ILS/web/js/ui/default/serial/subscription/issuance.js [new file with mode: 0644]
Open-ILS/web/opac/locale/en-US/lang.dtd
Open-ILS/web/templates/default/serial/list_stream.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/serial/list_subscription.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/serial/subscription.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/serial/subscription/caption_and_pattern.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/serial/subscription/distribution.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/serial/subscription/issuance.tt2 [new file with mode: 0644]
Open-ILS/xul/staff_client/chrome/content/cat/opac.js
Open-ILS/xul/staff_client/chrome/content/cat/opac.xul
Open-ILS/xul/staff_client/chrome/locale/en-US/offline.properties
Open-ILS/xul/staff_client/server/serial/batch_receive.js
Open-ILS/xul/staff_client/server/serial/pattern_wizard_overlay.xul

index 3151c01..62ea89c 100644 (file)
@@ -3170,12 +3170,24 @@ SELECT  usr,
                        <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 @@ SELECT  usr,
                <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 @@ SELECT  usr,
                        <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 @@ SELECT  usr,
                </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 @@ SELECT  usr,
                        <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>
 
index 5ea73e9..a7ab2d6 100644 (file)
@@ -1,6 +1,7 @@
 /* import the default css for the install applications */
 @import "default/acq.css";
 @import "default/admin.css";
+@import "default/serial.css";
 /* import the dojo CSS */
 @import "/js/dojo/dojo/resources/dojo.css";
 @import "/js/dojo/dijit/themes/tundra/tundra.css";
diff --git a/Open-ILS/web/css/skin/default/serial.css b/Open-ILS/web/css/skin/default/serial.css
new file mode 100644 (file)
index 0000000..8322252
--- /dev/null
@@ -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;
+}
index 6c26acd..692097e 100644 (file)
@@ -33,6 +33,27 @@ if(!dojo._hasResource["openils.XUL"]) {
         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.
      */
diff --git a/Open-ILS/web/js/ui/default/serial/list_stream.js b/Open-ILS/web/js/ui/default/serial/list_stream.js
new file mode 100644 (file)
index 0000000..e61127a
--- /dev/null
@@ -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();
+    }
+);
diff --git a/Open-ILS/web/js/ui/default/serial/list_subscription.js b/Open-ILS/web/js/ui/default/serial/list_subscription.js
new file mode 100644 (file)
index 0000000..206b730
--- /dev/null
@@ -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();
+            }
+        );
+    }
+);
diff --git a/Open-ILS/web/js/ui/default/serial/subscription.js b/Open-ILS/web/js/ui/default/serial/subscription.js
new file mode 100644 (file)
index 0000000..3f17749
--- /dev/null
@@ -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);
+    }
+);
diff --git a/Open-ILS/web/js/ui/default/serial/subscription/caption_and_pattern.js b/Open-ILS/web/js/ui/default/serial/subscription/caption_and_pattern.js
new file mode 100644 (file)
index 0000000..116cae2
--- /dev/null
@@ -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);
+}
diff --git a/Open-ILS/web/js/ui/default/serial/subscription/issuance.js b/Open-ILS/web/js/ui/default/serial/subscription/issuance.js
new file mode 100644 (file)
index 0000000..55dba09
--- /dev/null
@@ -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();
+    }
+}
index 9a9d904..66f01c3 100644 (file)
 <!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">
diff --git a/Open-ILS/web/templates/default/serial/list_stream.tt2 b/Open-ILS/web/templates/default/serial/list_stream.tt2
new file mode 100644 (file)
index 0000000..ea3f659
--- /dev/null
@@ -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 %]
diff --git a/Open-ILS/web/templates/default/serial/list_subscription.tt2 b/Open-ILS/web/templates/default/serial/list_subscription.tt2
new file mode 100644 (file)
index 0000000..7881779
--- /dev/null
@@ -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 %]
diff --git a/Open-ILS/web/templates/default/serial/subscription.tt2 b/Open-ILS/web/templates/default/serial/subscription.tt2
new file mode 100644 (file)
index 0000000..24970ad
--- /dev/null
@@ -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 %]
diff --git a/Open-ILS/web/templates/default/serial/subscription/caption_and_pattern.tt2 b/Open-ILS/web/templates/default/serial/subscription/caption_and_pattern.tt2
new file mode 100644 (file)
index 0000000..5510cdf
--- /dev/null
@@ -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>
diff --git a/Open-ILS/web/templates/default/serial/subscription/distribution.tt2 b/Open-ILS/web/templates/default/serial/subscription/distribution.tt2
new file mode 100644 (file)
index 0000000..8ad3a61
--- /dev/null
@@ -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>
diff --git a/Open-ILS/web/templates/default/serial/subscription/issuance.tt2 b/Open-ILS/web/templates/default/serial/subscription/issuance.tt2
new file mode 100644 (file)
index 0000000..55cf751
--- /dev/null
@@ -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>
index a23727d..b496f39 100644 (file)
@@ -303,6 +303,39 @@ function open_acq_orders() {
     }
 }
 
+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 open_marc_editor(rec, label) {
     };
 }
 
-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;
index 0c9396f..5197d89 100644 (file)
@@ -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>
index e7d0425..7fec403 100644 (file)
@@ -261,6 +261,7 @@ staff.cat.opac.title_for_hold_transfer.destination_needed.label=Need to mark a r
 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.):
index f43995d..7bbf383 100644 (file)
@@ -21,7 +21,7 @@ function F(k, args) {
 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 @@ function BatchReceiver() {
         this.item_cache = {};
 
         if (bib_id)
-            this.bib_lookup(bib_id, null, true);
+            this.bib_lookup(bib_id, null, true, sub_id);
 
         busy(false);
     };
@@ -454,7 +454,7 @@ function BatchReceiver() {
         }
     };
 
-    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) {
@@ -498,7 +498,7 @@ function BatchReceiver() {
                         } else {
                             self.bibdata = list[0];
                             self._show_bibdata_bits();
-                            self.choose_subscription();
+                            self.choose_subscription(sub_id);
                         }
                     } else {
                         alert(S("bib_lookup.not_found"));
@@ -514,7 +514,7 @@ function BatchReceiver() {
         );
     };
 
-    this.choose_subscription = function() {
+    this.choose_subscription = function(sub_id) {
         hide("batch_receive_bib");
         hide("batch_receive_entry");
         hide("batch_receive_sub_bits");
@@ -522,7 +522,11 @@ function BatchReceiver() {
 
         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");
 
@@ -913,6 +917,6 @@ function my_init() {
     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
     );
 }
index 47a8605..141bbb3 100644 (file)
                     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>