<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"/>
<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>
<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"/>
</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>
<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>
/* 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";
--- /dev/null
+.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;
+}
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.
*/
--- /dev/null
+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();
+ }
+);
--- /dev/null
+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();
+ }
+ );
+ }
+);
--- /dev/null
+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 = " " + 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);
+ }
+);
--- /dev/null
+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);
+}
--- /dev/null
+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();
+ }
+}
<!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">
--- /dev/null
+[% 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 %]
--- /dev/null
+[% 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 %]
--- /dev/null
+[% 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 %]
--- /dev/null
+<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>
--- /dev/null
+<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>
--- /dev/null
+<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>
}
}
+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 {
};
}
-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;
<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>
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.):
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});
this.item_cache = {};
if (bib_id)
- this.bib_lookup(bib_id, null, true);
+ this.bib_lookup(bib_id, null, true, sub_id);
busy(false);
};
}
};
- 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) {
} else {
self.bibdata = list[0];
self._show_bibdata_bits();
- self.choose_subscription();
+ self.choose_subscription(sub_id);
}
} else {
alert(S("bib_lookup.not_found"));
);
};
- this.choose_subscription = function() {
+ this.choose_subscription = function(sub_id) {
hide("batch_receive_bib");
hide("batch_receive_entry");
hide("batch_receive_sub_bits");
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");
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
);
}
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>